* Dynamic loading progress @ 2014-07-02 20:54 Aurélien Aptel 2014-07-02 21:33 ` Andreas Schwab 2014-07-04 1:26 ` Stefan Monnier 0 siblings, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2014-07-02 20:54 UTC (permalink / raw) To: Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 1731 bytes --] Hi, I've tried to test Dave Love's patch [1] but it's now bitrotten, I was not able to make it work. So I've started my own thing (drawn from Dave's initial work): * Use of libtool (ltdl) - add configure option for ltdl - update dependency in configure.ac / Makefile.in - add HAVE_LTDL test macro * New Lisp function `load-module' which takes a compiled module file path and loads it - check for plugin_is_GPL_compatible symbol - check presence of `init' symbol - run it as a void (*) () call (no return value/arg). At first I was calling the libtool init function (lt_dlinit) in syms_of_lread() but it made every subsequent call to lt_dlopen segfault. I think the problem was coming from calling it before dumping because as soon as I moved it to the body of `load-module' it started working. It works for very simple stuff so far. If I put a printf in the module init function it is called successfully. But as soon as I try to use DEFUN, gcc complains: In file included from fmod.c:17:0: fmod.c:30:16: error: ‘Ffmod’ undeclared here (not in a function) DEFUN ("fmod", Ffmod, Sfmod, 2, 2, 0, ^ emacs-master/src/lisp.h:2688:26: note: in definition of macro ‘DEFUN’ { .a ## maxargs = fnname }, \ ^ So I'm stuck here for now... Any help/feedback welcome :) I've attached a patch and an example module (compilation/loading instructions in comments). ltdl is enabled by default in the configure script, you just need libtool in order to try it. I know it is not as polished as Dave's patch, I'm just trying to get it to work before making it clean. 1: http://www.loveshack.ukfsn.org/emacs/dynamic-loading/ [-- Attachment #2: dynamic-loading.diff --] [-- Type: text/plain, Size: 4552 bytes --] diff -ru old/configure.ac new/configure.ac --- old/configure.ac 2014-07-01 16:06:11.000000000 +0200 +++ new/configure.ac 2014-07-01 19:28:08.030520500 +0200 @@ -323,6 +323,8 @@ OPTION_DEFAULT_ON([selinux],[don't compile with SELinux support]) OPTION_DEFAULT_ON([gnutls],[don't use -lgnutls for SSL/TLS support]) OPTION_DEFAULT_ON([zlib],[don't compile with zlib decompression support]) +OPTION_DEFAULT_ON([ltdl], [don't compile with dynamic module loading support]) + AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB], [use a file notification library (LIB one of: yes, gfile, inotify, w32, no)])], @@ -3126,6 +3128,18 @@ fi AC_SUBST(LIBZ) +HAVE_LTDL=no +LIBLTDL= +if test "${with_ltdl}" != "no"; then + AC_CHECK_HEADER(ltdl.h, HAVE_LTDL=yes, HAVE_LTDL=no) + AC_CHECK_LIB(ltdl, lt_dlopen, HAVE_LTDL=yes, HAVE_LTDL=no) +fi +if test "${HAVE_LTDL}" = "yes"; then + AC_DEFINE(HAVE_LTDL, 1, [Define to 1 if you have the ltdl library (-lltdl).]) + LIBLTDL=-lltdl +fi +AC_SUBST(LIBLTDL) + ### Use -lpng if available, unless `--with-png=no'. HAVE_PNG=no LIBPNG= @@ -4989,7 +5003,7 @@ emacs_config_features= for opt in XAW3D XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND GPM DBUS \ GCONF GSETTINGS NOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE M17N_FLT \ - LIBOTF XFT ZLIB; do + LIBOTF XFT ZLIB LTDL; do case $opt in NOTIFY|ACL) eval val=\${${opt}_SUMMARY} ;; @@ -5028,6 +5042,7 @@ echo " Does Emacs use -lotf? ${HAVE_LIBOTF}" echo " Does Emacs use -lxft? ${HAVE_XFT}" echo " Does Emacs directly use zlib? ${HAVE_ZLIB}" +echo " Does Emacs use -lltdl? ${HAVE_LTDL}" echo " Does Emacs use toolkit scroll bars? ${USE_TOOLKIT_SCROLL_BARS}" echo diff -ru old/src/lread.c new/src/lread.c --- old/src/lread.c 2014-07-01 16:06:11.000000000 +0200 +++ new/src/lread.c 2014-07-02 22:06:58.865218515 +0200 @@ -1,3 +1,4 @@ + /* Lisp parsing and input streams. Copyright (C) 1985-1989, 1993-1995, 1997-2014 Free Software Foundation, @@ -64,6 +65,10 @@ #define file_tell ftell #endif +#ifdef HAVE_LTDL +#include <ltdl.h> +#endif + /* Hash table read constants. */ static Lisp_Object Qhash_table, Qdata; static Lisp_Object Qtest, Qsize; @@ -999,6 +1004,49 @@ return Fnreverse (lst); } +DEFUN ("load-module", Fload_module, Sload_module, 1, 1, 0, + doc: /* Dymamically load a compiled module. */) + (Lisp_Object file) +{ +#ifdef HAVE_LTDL + static int lt_init_done = 0; + lt_dlhandle handle; + void (*module_init) (); + void *gpl_sym; + + if (!lt_init_done) + { + int ret = lt_dlinit (); + if (ret) + { + const char* s = lt_dlerror (); + error ("ltdl init fail: %s", s); + } + lt_init_done = 1; + } + + CHECK_STRING (file); + + handle = lt_dlopen (SDATA (file)); + if (!handle) + error ("Cannot load file %s", SDATA (file)); + + gpl_sym = lt_dlsym (handle, "plugin_is_GPL_compatible"); + if (!gpl_sym) + error ("Module %s is not GPL compatible", SDATA (file)); + + module_init = (void (*) ()) lt_dlsym (handle, "init"); + if (!module_init) + error ("Module %s does not have an init function.", SDATA (file)); + + module_init (); + + return Qt; +#else + return Qnil; +#endif +} + DEFUN ("load", Fload, Sload, 1, 5, 0, doc: /* Execute a file of Lisp code named FILE. First try FILE with `.elc' appended, then try with `.el', @@ -4486,6 +4534,7 @@ defsubr (&Sget_file_char); defsubr (&Smapatoms); defsubr (&Slocate_file_internal); + defsubr (&Sload_module); DEFVAR_LISP ("obarray", Vobarray, doc: /* Symbol table for use by `intern' and `read'. Only in new/src: lread.o Only in new/src: macros.o Only in new/src: Makefile diff -ru old/src/Makefile.in new/src/Makefile.in --- old/src/Makefile.in 2014-07-01 16:06:11.000000000 +0200 +++ new/src/Makefile.in 2014-07-01 19:35:02.941344222 +0200 @@ -225,6 +225,8 @@ LIBZ = @LIBZ@ +LIBLTDL = @LIBLTDL@ + XRANDR_LIBS = @XRANDR_LIBS@ XRANDR_CFLAGS = @XRANDR_CFLAGS@ @@ -408,7 +410,7 @@ $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) \ - $(GFILENOTIFY_LIBS) $(LIB_MATH) $(LIBZ) + $(GFILENOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBLTDL) all: emacs$(EXEEXT) $(OTHER_FILES) .PHONY: all [-- Attachment #3: fmod.c --] [-- Type: text/x-csrc, Size: 818 bytes --] /* example module compilation: $ gcc -Wall -Iemacs/src -Iemacs/lib -fPIC -c fmod.c $ gcc -shared -o fmod.so fmod.o loading: $ ./emacs -Q --batch --eval '(load-module "../../fmod.so")' hello world */ #include <config.h> #include <lisp.h> #include <math.h> #include <stdio.h> /* emacs checks for this symbol before running the module */ int plugin_is_GPL_compatible; /* XXX: DEFUN doesn't work yet... :( */ #if 0 /* define a new lisp function */ DEFUN ("fmod", Ffmod, Sfmod, 2, 2, 0, doc: /* Returns the floating-point remainder of NUMER/DENOM */) (Lisp_Object numer, Lisp_Object denom) { return make_float (fmod (extract_float (numer), extract_float (denom))); } #endif /* entry point of the module */ void init () { // defsubr (&Sfmod); printf ("hello world\n"); } ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-07-02 20:54 Dynamic loading progress Aurélien Aptel @ 2014-07-02 21:33 ` Andreas Schwab 2014-07-03 17:09 ` Aurélien Aptel 2014-07-04 1:26 ` Stefan Monnier 1 sibling, 1 reply; 765+ messages in thread From: Andreas Schwab @ 2014-07-02 21:33 UTC (permalink / raw) To: Aurélien Aptel; +Cc: Emacs development discussions Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: > It works for very simple stuff so far. If I put a printf in the module > init function it is called successfully. But as soon as I try to use > DEFUN, gcc complains: > > In file included from fmod.c:17:0: > fmod.c:30:16: error: ‘Ffmod’ undeclared here (not in a function) > DEFUN ("fmod", Ffmod, Sfmod, 2, 2, 0, > ^ > emacs-master/src/lisp.h:2688:26: note: in definition of macro ‘DEFUN’ > { .a ## maxargs = fnname }, \ > ^ > > So I'm stuck here for now... Any help/feedback welcome :) You need to declare Ffmod with EXFUN. Andreas. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-07-02 21:33 ` Andreas Schwab @ 2014-07-03 17:09 ` Aurélien Aptel 2014-07-03 17:43 ` Dmitry Antipov 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2014-07-03 17:09 UTC (permalink / raw) To: Andreas Schwab; +Cc: Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 1965 bytes --] On Wed, Jul 2, 2014 at 11:33 PM, Andreas Schwab <schwab@linux-m68k.org> wrote: > You need to declare Ffmod with EXFUN. Thanks, it almost worked. In order to use emacs symbols from a dynamically loaded module I had to add a linker option to export the symbols from emacs. The option is -Wl,--export-dynamic. (updated in configure.ac) I then ran into another problem: the module is loaded correctly but emacs_abort() is called inside defsubr(). The actual call was in intern_c_string_1 where I made the following change: Lisp_Object intern_c_string_1 (const char *str, ptrdiff_t len) { Lisp_Object obarray = check_obarray (Vobarray); Lisp_Object tem = oblookup (obarray, str, len, len); if (SYMBOLP (tem)) return tem; if (NILP (Vpurify_flag)) - /* Creating a non-pure string from a string literal not - implemented yet. We could just use make_string here and live - with the extra copy. */ - emacs_abort (); + return Fintern (make_string (str, len), obarray); return Fintern (make_pure_c_string (str, len), obarray); } I'm not familiar with all the dumping intricacies but judging from the comment this change seems harmless (Can someone confirm this?). I've made a modules directory with the sample module and a Makefile which has to be run separately for now. Here's the whole procedure the test it for anyone interested: # get a recent copy of emacs sources $ wget -O e.zip https://github.com/mirrors/emacs/archive/master.zip $ unzip e.zip # apply attached diff $ cd emacs-master $ patch -p1 < path/to/dynamic-loading-2.diff # compile $ ./autogen.sh && ./configure && make -j8 # compile & test module $ make -C modules $ ./src/emacs -Q --batch --eval '(progn (load-module "modules/fmod.so") (message "%f" (fmod 2.4 2)))' 0.400000 Pretty cool if you ask me :) The next steps are: - handle doc strings - handle features related stuff (provide, require, run-after-load hooks, ...) - making it portable - ? [-- Attachment #2: dynamic-loading-2.diff --] [-- Type: text/plain, Size: 6184 bytes --] diff --git a/configure.ac b/configure.ac index 04c75e3..2614f46 100644 --- a/configure.ac +++ b/configure.ac @@ -323,6 +323,8 @@ OPTION_DEFAULT_ON([gsettings],[don't compile with GSettings support]) OPTION_DEFAULT_ON([selinux],[don't compile with SELinux support]) OPTION_DEFAULT_ON([gnutls],[don't use -lgnutls for SSL/TLS support]) OPTION_DEFAULT_ON([zlib],[don't compile with zlib decompression support]) +OPTION_DEFAULT_ON([ltdl], [don't compile with dynamic module loading support]) + AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB], [use a file notification library (LIB one of: yes, gfile, inotify, w32, no)])], @@ -3126,6 +3128,18 @@ if test "${HAVE_ZLIB}" = "yes"; then fi AC_SUBST(LIBZ) +HAVE_LTDL=no +LIBLTDL= +if test "${with_ltdl}" != "no"; then + AC_CHECK_HEADER(ltdl.h, HAVE_LTDL=yes, HAVE_LTDL=no) + AC_CHECK_LIB(ltdl, lt_dlopen, HAVE_LTDL=yes, HAVE_LTDL=no) +fi +if test "${HAVE_LTDL}" = "yes"; then + AC_DEFINE(HAVE_LTDL, 1, [Define to 1 if you have the ltdl library (-lltdl).]) + LIBLTDL="-lltdl -Wl,--export-dynamic" +fi +AC_SUBST(LIBLTDL) + ### Use -lpng if available, unless `--with-png=no'. HAVE_PNG=no LIBPNG= @@ -4989,7 +5003,7 @@ optsep= emacs_config_features= for opt in XAW3D XPM JPEG TIFF GIF PNG RSVG IMAGEMAGICK SOUND GPM DBUS \ GCONF GSETTINGS NOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE M17N_FLT \ - LIBOTF XFT ZLIB; do + LIBOTF XFT ZLIB LTDL; do case $opt in NOTIFY|ACL) eval val=\${${opt}_SUMMARY} ;; @@ -5028,6 +5042,7 @@ echo " Does Emacs use -lm17n-flt? ${HAVE_M17N_FLT} echo " Does Emacs use -lotf? ${HAVE_LIBOTF}" echo " Does Emacs use -lxft? ${HAVE_XFT}" echo " Does Emacs directly use zlib? ${HAVE_ZLIB}" +echo " Does Emacs use -lltdl? ${HAVE_LTDL}" echo " Does Emacs use toolkit scroll bars? ${USE_TOOLKIT_SCROLL_BARS}" echo diff --git a/modules/Makefile b/modules/Makefile new file mode 100644 index 0000000..52fb876 --- /dev/null +++ b/modules/Makefile @@ -0,0 +1,8 @@ + +all: fmod.so + +%.so: %.o + gcc -shared -o $@ $< + +%.o: %.c + gcc -ggdb3 -Wall -I../src -I../lib -fPIC -c $< diff --git a/modules/fmod.c b/modules/fmod.c new file mode 100644 index 0000000..2fdd01e --- /dev/null +++ b/modules/fmod.c @@ -0,0 +1,25 @@ +#include <config.h> +#include <lisp.h> + +#include <math.h> + +/* emacs checks for this symbol before running the module */ + +int plugin_is_GPL_compatible; + +/* define a new lisp function */ + +EXFUN (Ffmod, 2); +DEFUN ("fmod", Ffmod, Sfmod, 2, 2, 0, + doc: "Returns the floating-point remainder of NUMER/DENOM") + (Lisp_Object numer, Lisp_Object denom) +{ + return make_float (fmod (extract_float (numer), extract_float (denom))); +} + +/* entry point of the module */ + +void init () +{ + defsubr (&Sfmod); +} diff --git a/src/Makefile.in b/src/Makefile.in index a13f7b8..780245a 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -225,6 +225,8 @@ LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ LIBZ = @LIBZ@ +LIBLTDL = @LIBLTDL@ + XRANDR_LIBS = @XRANDR_LIBS@ XRANDR_CFLAGS = @XRANDR_CFLAGS@ @@ -408,7 +410,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \ $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) \ - $(GFILENOTIFY_LIBS) $(LIB_MATH) $(LIBZ) + $(GFILENOTIFY_LIBS) $(LIB_MATH) $(LIBZ) $(LIBLTDL) all: emacs$(EXEEXT) $(OTHER_FILES) .PHONY: all diff --git a/src/lread.c b/src/lread.c index f252993..e431be6 100644 --- a/src/lread.c +++ b/src/lread.c @@ -1,3 +1,4 @@ + /* Lisp parsing and input streams. Copyright (C) 1985-1989, 1993-1995, 1997-2014 Free Software Foundation, @@ -64,6 +65,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #define file_tell ftell #endif +#ifdef HAVE_LTDL +#include <ltdl.h> +#endif + /* Hash table read constants. */ static Lisp_Object Qhash_table, Qdata; static Lisp_Object Qtest, Qsize; @@ -999,6 +1004,49 @@ This uses the variables `load-suffixes' and `load-file-rep-suffixes'. */) return Fnreverse (lst); } +DEFUN ("load-module", Fload_module, Sload_module, 1, 1, 0, + doc: /* Dymamically load a compiled module. */) + (Lisp_Object file) +{ +#ifdef HAVE_LTDL + static int lt_init_done = 0; + lt_dlhandle handle; + void (*module_init) (); + void *gpl_sym; + + if (!lt_init_done) + { + int ret = lt_dlinit (); + if (ret) + { + const char* s = lt_dlerror (); + error ("ltdl init fail: %s", s); + } + lt_init_done = 1; + } + + CHECK_STRING (file); + + handle = lt_dlopen (SDATA (file)); + if (!handle) + error ("Cannot load file %s", SDATA (file)); + + gpl_sym = lt_dlsym (handle, "plugin_is_GPL_compatible"); + if (!gpl_sym) + error ("Module %s is not GPL compatible", SDATA (file)); + + module_init = (void (*) ()) lt_dlsym (handle, "init"); + if (!module_init) + error ("Module %s does not have an init function.", SDATA (file)); + + module_init (); + + return Qt; +#else + return Qnil; +#endif +} + DEFUN ("load", Fload, Sload, 1, 5, 0, doc: /* Execute a file of Lisp code named FILE. First try FILE with `.elc' appended, then try with `.el', @@ -3805,10 +3853,7 @@ intern_c_string_1 (const char *str, ptrdiff_t len) return tem; if (NILP (Vpurify_flag)) - /* Creating a non-pure string from a string literal not - implemented yet. We could just use make_string here and live - with the extra copy. */ - emacs_abort (); + return Fintern (make_string (str, len), obarray); return Fintern (make_pure_c_string (str, len), obarray); } @@ -4486,6 +4531,7 @@ syms_of_lread (void) defsubr (&Sget_file_char); defsubr (&Smapatoms); defsubr (&Slocate_file_internal); + defsubr (&Sload_module); DEFVAR_LISP ("obarray", Vobarray, doc: /* Symbol table for use by `intern' and `read'. ^ permalink raw reply related [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-07-03 17:09 ` Aurélien Aptel @ 2014-07-03 17:43 ` Dmitry Antipov 2014-07-03 19:44 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Dmitry Antipov @ 2014-07-03 17:43 UTC (permalink / raw) To: Aurélien Aptel; +Cc: Emacs development discussions On 07/03/2014 09:09 PM, Aurélien Aptel wrote: > The next steps are: > - handle doc strings > - handle features related stuff (provide, require, run-after-load hooks, ...) > - making it portable > - ? IMHO unloading should be the first item in this list. (I'm curious whether we have a method to undo defsubr). And lread.c is about reading input streams, so it's better to move module-related stuff in fns.c. Dmitry ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-07-03 17:43 ` Dmitry Antipov @ 2014-07-03 19:44 ` Stefan Monnier 0 siblings, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2014-07-03 19:44 UTC (permalink / raw) To: Dmitry Antipov; +Cc: Aurélien Aptel, Emacs development discussions > IMHO unloading should be the first item in this list. Unloading of Elisp packages is barely supported, so unloading of FFI packages is not very high priority for me. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-07-02 20:54 Dynamic loading progress Aurélien Aptel 2014-07-02 21:33 ` Andreas Schwab @ 2014-07-04 1:26 ` Stefan Monnier 2014-07-06 15:14 ` Aurélien Aptel 2014-09-24 14:20 ` Ted Zlatanov 1 sibling, 2 replies; 765+ messages in thread From: Stefan Monnier @ 2014-07-04 1:26 UTC (permalink / raw) To: Aurélien Aptel; +Cc: Emacs development discussions > At first I was calling the libtool init function (lt_dlinit) in > syms_of_lread() but it made every subsequent call to lt_dlopen > segfault. I think the problem was coming from calling it before > dumping because as soon as I moved it to the body of `load-module' it > started working. It should maybe be called in an init_* function rather than a syms_of_* function: the difference is that syms_of_* functions are called only once, before dumping, whereas the init_* functions are re-executed every time Emacs is started (i.e. before and after the dump). But calling it from Fload_module is probably fine as well (and maybe even better). > - /* Creating a non-pure string from a string literal not > - implemented yet. We could just use make_string here and live > - with the extra copy. */ > - emacs_abort (); > + return Fintern (make_string (str, len), obarray); That's OK, tho you might keep a comment about the need to make a duplicate copy of the string because a heap-allocated Lisp_String can't point to a string literal. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-07-04 1:26 ` Stefan Monnier @ 2014-07-06 15:14 ` Aurélien Aptel 2014-07-07 1:19 ` Stefan Monnier 2014-09-24 14:20 ` Ted Zlatanov 1 sibling, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2014-07-06 15:14 UTC (permalink / raw) To: Stefan Monnier; +Cc: Emacs development discussions I've focused on the docstring part these last few days. Dave's patch was using Emacs' make-docfile utility to generate a .doc file (from a .c file) per module which was loaded along the module by calling its own version of snarf_documentation that skipped some checks. I've tried to do the same thing but there are several problems which I suspect where already there in Dave's patch. The doc member of a subr struct is not a pointer to the doc string but an offset in the build global doc file (Vfile_doc_name aka etc/DOC). This saves memory but since we now have multiple doc files it doesn't work. If you update Vfile_doc_name to the module's doc file, Fdocumentation will only work on this module's functions. We could: - switch back to storing the doc string in memory for modules - make an alist or something to map a function name to a doc file - <your alternative solution> ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-07-06 15:14 ` Aurélien Aptel @ 2014-07-07 1:19 ` Stefan Monnier 2014-07-09 21:02 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2014-07-07 1:19 UTC (permalink / raw) To: Aurélien Aptel; +Cc: Emacs development discussions > The doc member of a subr struct is not a pointer to the doc string but > an offset in the build global doc file (Vfile_doc_name aka etc/DOC). > This saves memory but since we now have multiple doc files it doesn't > work. If you update Vfile_doc_name to the module's doc file, > Fdocumentation will only work on this module's functions. The `doc' field could simply be changed to be of type Lisp_Object and then follow the usual representation used for lambda expressions and variables where it can be: - a single integer: an offset into the one true DOC file. - a cons (FILE . OFFSET): says that the doc can be found in FILE starting at OFFSET. - a string. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-07-07 1:19 ` Stefan Monnier @ 2014-07-09 21:02 ` Aurélien Aptel 2014-07-09 22:18 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2014-07-09 21:02 UTC (permalink / raw) To: Stefan Monnier; +Cc: Emacs development discussions I've made a github repo of my work so far: https://github.com/aaptel/emacs-dynamic-module On Mon, Jul 7, 2014 at 3:19 AM, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > The `doc' field could simply be changed to be of type Lisp_Object and > then follow the usual representation used for lambda expressions I've followed your advice. a) I've updated the type of the doc field. I'm initializing it to 0 in the DEFUN macro and I set it to Qnil in defsubr(). I'm not initializing the field directly to Qnil because the docs reads: You must not use C initializers for static or global variables unless the variables are never written once Emacs is dumped. These variables with initializers are allocated in an area of memory that becomes read-only (on certain operating systems) as a result of dumping Emacs. See Pure Storage. Instead of duplicating the Fsnarf_documentation code for handling modules I've added a boolean 'module' parameter. If the function snarfs a module documentation, don't overwrite the global DOC file path and store a (FILE . OFFSET) cons instead of a simple offset. This part works correctly. b) Now, when fetching a function docstring with Fdocumentation, I check the types and let the existing get_doc_string() handle the field itself. It should work but I've ran into a strange problem: the doc field is set correctly in step a) but the field becomes either an invalid lisp object or garbage at step b). I've added debug print statement (using safe_debug_print): # this is after calling load-module --- fmod ("/home/knarf/prog/c/emacs/dyn/modules/fmod.doc" . -16) --- --- fmod-test1 ("/home/knarf/prog/c/emacs/dyn/modules/fmod.doc" . -98) --- --- fmod-test2 ("/home/knarf/prog/c/emacs/dyn/modules/fmod.doc" . -125) --- --- fmod-test3 ("/home/knarf/prog/c/emacs/dyn/modules/fmod.doc" . -152) --- # now calling (documentation 'fmod...) --Fdocumentation fmod #<INVALID_LISP_OBJECT 0x0322a986> --- --Fdocumentation fmod-test1 #<INVALID_LISP_OBJECT 0x0322a996> --- --Fdocumentation fmod-test2 ((keymap #^[nil nil keymap #^^[3 0 set-mark-comma... # [garbage] --- It suspect it has to do with garbage collecting since I have not done anything special to protect the doc field. I'm not sure how to proceed. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-07-09 21:02 ` Aurélien Aptel @ 2014-07-09 22:18 ` Stefan Monnier 2014-07-10 17:21 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2014-07-09 22:18 UTC (permalink / raw) To: Aurélien Aptel; +Cc: Emacs development discussions > It should work but I've ran into a strange problem: the doc field is > set correctly in step a) but the field becomes either an invalid lisp > object or garbage at step b). [...] > It suspect it has to do with garbage collecting since I have not done > anything special to protect the doc field. I'm not sure how to > proceed. Right. You need to tell the GC to trace this new field. Look at the mark_object function in alloc.c. You could change its handling of PVEC_SUBR such that it calls itself recursively on the `doc' field and then make sure the VECTOR_MARKED_P bit gets reset to false in gc_sweep. Or maybe force those `doc' references to be kept alive by adding globally reachable references to them (e.g. have a global list of all the cons cells you ever added to such a `doc' field, and then `staticpro' that list). Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-07-09 22:18 ` Stefan Monnier @ 2014-07-10 17:21 ` Aurélien Aptel 2014-07-10 18:04 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2014-07-10 17:21 UTC (permalink / raw) To: Stefan Monnier; +Cc: Emacs development discussions On Thu, Jul 10, 2014 at 12:18 AM, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > You could change its handling of PVEC_SUBR such that it calls itself > recursively on the `doc' field and then make sure the VECTOR_MARKED_P bit > gets reset to false in gc_sweep. I understand that marking a symbol which is bound to a subr means we have to mark the subr i.e. the doc field since we can't free a subr. But why do we need to do something else? The doc string being either a cons, an int or a string it will be automatically handled in the respective sweep_xxx functions. There are no global list of subr that can be swept AFAIK. I've only made the mark_object() recursive call. Getting a module documentation still doesn't work but at least the conses are valid now. > Or maybe force those `doc' references to be kept alive by adding > globally reachable references to them (e.g. have a global list of all > the cons cells you ever added to such a `doc' field, and then > `staticpro' that list). The first solution is better IMHO, it's more intrusive but it limits the scope of the problem to the GC. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-07-10 17:21 ` Aurélien Aptel @ 2014-07-10 18:04 ` Stefan Monnier 2014-07-11 9:01 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2014-07-10 18:04 UTC (permalink / raw) To: Aurélien Aptel; +Cc: Emacs development discussions >> You could change its handling of PVEC_SUBR such that it calls itself >> recursively on the `doc' field and then make sure the VECTOR_MARKED_P bit >> gets reset to false in gc_sweep. > I understand that marking a symbol which is bound to a subr means we > have to mark the subr i.e. the doc field since we can't free a subr. > But why do we need to do something else? The doc string being either a > cons, an int or a string it will be automatically handled in the > respective sweep_xxx functions. There are no global list of subr that > can be swept AFAIK. The issue is that when we get a vectorlike object, the first thing we want to do is to check the VECTOR_MARKED_P and stop right there if it's already marked. So in order to look inside the Subrs, we'd either have to check SUBRP before checking VECTOR_MARKED_P (thus slowing doing GC for every one), or we'd have to make sure that the SUBRP that are dyn-loaded have a VECTOR_MARKED_P that says false (either always or at least a the beginning of the GC). > The first solution is better IMHO, it's more intrusive but it limits > the scope of the problem to the GC. I tend to agree. Maybe resetting VECTOR_MARKED_P on Subrs to false directly from mark_object (and only if the `doc' field is non-trivial) is the easiest solution. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-07-10 18:04 ` Stefan Monnier @ 2014-07-11 9:01 ` Aurélien Aptel 2014-07-11 13:27 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2014-07-11 9:01 UTC (permalink / raw) To: Stefan Monnier; +Cc: Emacs development discussions Sorry, I still don't get it. On Thu, Jul 10, 2014 at 8:04 PM, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > The issue is that when we get a vectorlike object, the first thing we > want to do is to check the VECTOR_MARKED_P and stop right there if it's > already marked. You're talking about the marking pass here, right? in mark_object (): case Lisp_Vectorlike: { register struct Lisp_Vector *ptr = XVECTOR (obj); register ptrdiff_t pvectype; if (VECTOR_MARKED_P (ptr)) break; If it's already marked, then the doc field is already marked too so breaking here is correct. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-07-11 9:01 ` Aurélien Aptel @ 2014-07-11 13:27 ` Stefan Monnier 0 siblings, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2014-07-11 13:27 UTC (permalink / raw) To: Aurélien Aptel; +Cc: Emacs development discussions > If it's already marked, then the doc field is already marked too so > breaking here is correct. But if "it's already marked" there are two possible cases: - it was just marked earlier in the current GC and indeed then we're good to go. - it was marked in some earlier GC and the mark was not reset since then (normally, all marks are reset during gc_sweep, but this is currently not done for Subrs, AFAIK). In that case we're in trouble, because the doc needs to be re-marked during this GC, otherwise it might get reclaimed. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-07-04 1:26 ` Stefan Monnier 2014-07-06 15:14 ` Aurélien Aptel @ 2014-09-24 14:20 ` Ted Zlatanov 2014-09-24 17:27 ` Stefan Monnier 1 sibling, 1 reply; 765+ messages in thread From: Ted Zlatanov @ 2014-09-24 14:20 UTC (permalink / raw) To: emacs-devel On Thu, 3 Jul 2014 19:09:46 +0200 Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: AA> Pretty cool if you ask me :) It's absolutely wonderful. AA> The next steps are: AA> - handle doc strings AA> - handle features related stuff (provide, require, run-after-load hooks, ...) AA> - making it portable AA> - ? I am assuming that structurally, your code is OK with all the developers, because we've had no protests :) I'd love to get a version of this in a branch and try it for JSON and YAML parsing library integration. Is it ready for that kind of abuse? Portability is not a big deal IMO, it's OK to start with GNU/Linux support. We previously discussed signed modules in addition to unsigned. Can your patch provide that? Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-09-24 14:20 ` Ted Zlatanov @ 2014-09-24 17:27 ` Stefan Monnier 2014-09-25 12:41 ` Ted Zlatanov 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2014-09-24 17:27 UTC (permalink / raw) To: emacs-devel > I'd love to get a version of this in a branch and try it for JSON and > YAML parsing library integration. Is it ready for that kind of abuse? AFAIC, it's OK to start installing such experimental code in trunk, as long as it's properly #ifdef'd. > We previously discussed signed modules in addition to unsigned. Can your > patch provide that? The FFI itself shouldn't care about signed modules. This should be done by the module download&installation code (which should most likely be in package.el). Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-09-24 17:27 ` Stefan Monnier @ 2014-09-25 12:41 ` Ted Zlatanov 2014-10-09 17:08 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Ted Zlatanov @ 2014-09-25 12:41 UTC (permalink / raw) To: emacs-devel On Wed, 24 Sep 2014 13:27:39 -0400 Stefan Monnier <monnier@iro.umontreal.ca> wrote: >> We previously discussed signed modules in addition to unsigned. Can your >> patch provide that? SM> The FFI itself shouldn't care about signed modules. This should be done SM> by the module download&installation code (which should most likely be SM> in package.el). I personally wouldn't make it trivially easy to circumvent in ELisp, but it was not a blocking question anyhow. The key is to get the basics working as you mentioned. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-09-25 12:41 ` Ted Zlatanov @ 2014-10-09 17:08 ` Aurélien Aptel 2014-10-09 17:11 ` Aurélien Aptel ` (2 more replies) 0 siblings, 3 replies; 765+ messages in thread From: Aurélien Aptel @ 2014-10-09 17:08 UTC (permalink / raw) To: Emacs development discussions Good news everyone! As of my last commit (7a38270cd) dynamic loading is working pretty well. I've written a few toy modules in the "modules" folder. They can be used as examples and cover various use-case. - The `fmod' module simply expose the fmod(3) function from the math lib. - The `elisp' module evaluates code written in Lisp from C. - The `opaque' module show how any C structs/type can be embedded in a Lisp_Object. - The `curl' module can actually be useful as it links against libcurl and lets you fetch any http url supported by curl. You can use the same curl handle for multiple request in order to reuse the connection when possible (faster!). * Usage Dynamic loading can be enabled/disabled via the configure script. libltdl/ltdl.h is all you need to make it work. I've turned the option on by default (--with-ltdl). # build emacs $ git clone https://github.com/aaptel/emacs-dynamic-module.git emacs-dyn $ cd emacs-dyn $ ./autogen.sh $ ./configure $ make # build all the modules $ for i in modules/*; do make -C "$i"; done # run emacs! (no init file) $ ./src/emacs -Q Switch to *scratch* to test interactively the curl module: (add-to-list 'load-path "path/to/emacs/modules/curl") (require 'curl) => t ;; alternatively you can use ;; (load "path/to/curl/curl.so") ;; or ;; (load-module "path/to/curl/curl.so") (defvar c) (setq c (curl-make)) ;; allocate/init a curl handle => #<save-value <pointer 0x1cf56d0> <unused> <unused> <unused>> (curl-fetch-url c "http://example.com") ;; make and store request => t (curl-content c) "<!doctype html> <html> <head> <title>Example Domain</title> ..." (curl-free c) ;; free the curl handle => t I've just tested the build procedure above before posting and *of course* for some reason a clean emacs build fail on something completely unrelated. Even at my first commit where I didn't make any change yet. make[1]: *** No rule to make target 'ctags.c', needed by 'ctags'. Stop. I suppose it comes from my setup? Gahh.. Anyway... * Implementation details and potential issues ** Loading The actual loading is done in Fload_module in lread.c. It is called from Fload when appropriate. See my previous emails. When dynamic modules are enabled, the `load-suffixes' variable has the additional .so suffix. This variable is used by `load' which in turn calls openp() to do the actual search in `load-path'. Adapting `load' to support modules made `require' and `provide' work with no additional work. Nothing is preventing a module from being loaded several times apart from the `features' mechanism. This might be problematic. ** Documentation I have updated several documentation related functions in order to support multiple DOCFILE (each module has its own). See my previous emails. The xref on function documentation (go to definition) is currently broken. I have not looked into it (issue #6). I have not fixed the issue (#1) Stefan mentioned earlier about a memory leak in the GC on the subr doc field because I *still* don't get it :( Any help is welcomed. ** Opaque user types Adding a new proper type is too much work for a module. You need to provide a reader, a printer, add a bunch of enums, etc. I've reused the Save_Value type to store arbitrary pointers. The object hierarchy is as follows: Lisp_Object > Lisp_Misc > Lisp_Save_Value > void* pointer A major problem with this is that you can't make type predicates e.g. `curl-handle-p'. A solution would be to make a new generic user type composed of a user pointer and a cookie or some sort of ID we can test. The space has to be large enough to limit collisions. ** Resource management An allocated curl handle has to be explicitly freed with `curl-free'. Could we extend the GC to provide some sort of destructor mechanism? Just a thought. Also, Lisp_Objects contained in a user type are not protected from the GC. This can be a problem. ** Native type size EMACS_INT_MAX is not always equal to INT_MAX depending on the architecture. Libraries can often use special value to signal something (e.g. (unsigned)-1 which is 0xffff..) which might not be fit in a Lisp type. What can we do about it? Is it really a problem? Emacs Lisp provides other way to signal errors and a module doesn't have to expose low-level stuff like this. ** Packaging Right now each module has its own Makefile and is built separately from emacs. We need to think of a way to package modules for distribution that is practical and takes into account what the module needs from the Emacs build (which configure option should be enabled to build module xxx?). ** Portability The .so suffix is hardcoded but via libltdl loading should work on most systems. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-09 17:08 ` Aurélien Aptel @ 2014-10-09 17:11 ` Aurélien Aptel 2014-10-09 17:27 ` Eli Zaretskii 2014-12-27 21:57 ` Stephen Leake 2 siblings, 0 replies; 765+ messages in thread From: Aurélien Aptel @ 2014-10-09 17:11 UTC (permalink / raw) To: Emacs development discussions Just a few things I forgot: You can find more in commit messages and in the issue tracker. https://github.com/aaptel/emacs-dynamic-module/commits/master https://github.com/aaptel/emacs-dynamic-module/issues ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-09 17:08 ` Aurélien Aptel 2014-10-09 17:11 ` Aurélien Aptel @ 2014-10-09 17:27 ` Eli Zaretskii 2014-10-09 19:42 ` Stefan Monnier 2014-10-10 15:05 ` Aurélien Aptel 2014-12-27 21:57 ` Stephen Leake 2 siblings, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2014-10-09 17:27 UTC (permalink / raw) To: Aurélien Aptel; +Cc: emacs-devel > Date: Thu, 9 Oct 2014 19:08:47 +0200 > From: Aurélien Aptel <aurelien.aptel+emacs@gmail.com> > > As of my last commit (7a38270cd) dynamic loading is working pretty > well. Thanks. > ;; alternatively you can use > ;; (load "path/to/curl/curl.so") > ;; or > ;; (load-module "path/to/curl/curl.so") The .so extension is platform specific. Since Emacs tries to keep platform dependencies out of the Lisp level, how about chopping the extension, and adding to load-module the necessary code to look for the extension specific to the underlying platform? > ** Portability > > The .so suffix is hardcoded but via libltdl loading should work on > most systems. Well, how about removing this issue by using lt_dlopenext? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-09 17:27 ` Eli Zaretskii @ 2014-10-09 19:42 ` Stefan Monnier 2014-10-09 21:17 ` Eli Zaretskii 2014-10-10 15:05 ` Aurélien Aptel 1 sibling, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2014-10-09 19:42 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Aurélien Aptel, emacs-devel > The .so extension is platform specific. Since Emacs tries to keep > platform dependencies out of the Lisp level, how about chopping the > extension, and adding to load-module the necessary code to look for > the extension specific to the underlying platform? I think we can circumvent this problem by changing the suffix we add to load-suffixes depending on the platform (e.g. based on dlopenext). Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-09 19:42 ` Stefan Monnier @ 2014-10-09 21:17 ` Eli Zaretskii 2014-10-10 0:53 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2014-10-09 21:17 UTC (permalink / raw) To: Stefan Monnier; +Cc: aurelien.aptel+emacs, emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: Aurélien Aptel <aurelien.aptel+emacs@gmail.com>, > emacs-devel@gnu.org > Date: Thu, 09 Oct 2014 15:42:35 -0400 > > > The .so extension is platform specific. Since Emacs tries to keep > > platform dependencies out of the Lisp level, how about chopping the > > extension, and adding to load-module the necessary code to look for > > the extension specific to the underlying platform? > > I think we can circumvent this problem by changing the suffix we add to > load-suffixes depending on the platform (e.g. based on dlopenext). You mean, use foo.so in Lisp and have .so changed to something else? That's ugly, and we never do that anywhere else. Why start now? Just use "foo" and set up the extensions as appropriate for the platform, as we do with programs. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-09 21:17 ` Eli Zaretskii @ 2014-10-10 0:53 ` Stefan Monnier 2014-10-10 6:32 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2014-10-10 0:53 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, emacs-devel >> I think we can circumvent this problem by changing the suffix we add to >> load-suffixes depending on the platform (e.g. based on dlopenext). > You mean, use foo.so in Lisp and have .so changed to something else? No, I means to add ".so" or ".dll" to `load-suffixes' depending on the host system. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-10 0:53 ` Stefan Monnier @ 2014-10-10 6:32 ` Eli Zaretskii 2014-10-10 12:54 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2014-10-10 6:32 UTC (permalink / raw) To: Stefan Monnier; +Cc: aurelien.aptel+emacs, emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: aurelien.aptel+emacs@gmail.com, emacs-devel@gnu.org > Date: Thu, 09 Oct 2014 20:53:13 -0400 > > >> I think we can circumvent this problem by changing the suffix we add to > >> load-suffixes depending on the platform (e.g. based on dlopenext). > > You mean, use foo.so in Lisp and have .so changed to something else? > > No, I means to add ".so" or ".dll" to `load-suffixes' depending on the > host system. In that case, that's what I was proposing. I think. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-10 6:32 ` Eli Zaretskii @ 2014-10-10 12:54 ` Stefan Monnier 0 siblings, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2014-10-10 12:54 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, emacs-devel >> >> I think we can circumvent this problem by changing the suffix we add to >> >> load-suffixes depending on the platform (e.g. based on dlopenext). >> > You mean, use foo.so in Lisp and have .so changed to something else? >> No, I means to add ".so" or ".dll" to `load-suffixes' depending on the >> host system. > In that case, that's what I was proposing. I think. Yes, I think we're in violent agreement, Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-09 17:27 ` Eli Zaretskii 2014-10-09 19:42 ` Stefan Monnier @ 2014-10-10 15:05 ` Aurélien Aptel 2014-10-10 15:50 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2014-10-10 15:05 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Emacs development discussions On Thu, Oct 9, 2014 at 7:27 PM, Eli Zaretskii <eliz@gnu.org> wrote: > Well, how about removing this issue by using lt_dlopenext? I use the .so extension to know whether a file is a binary module or elisp (compiled or source). In order to let libltdl guess & try various extensions with dlopenext I have to leave `load-suffixes' alone and try to load the file as a module everytime. If it's actually a module, continue loading it, else load as elisp. I find this messy. What Stefan is proposing is to add the plateform specific suffixes in `load-suffixes' at compilation time. Somehing like this: /* Somwhere in a platform abstraction header (which one?) (I don't know the actual system defines) */ #ifdef HAVE_LTDL #if defined(WINDOWS) #define MODULE_SUFFIX ".dll" #elif defined(UNIX) #define MODULE_SUFFIX ".so" #elif defined(MAC) #define MODULE_SUFFIX ".dylib" #else #error "Modules not supported on this system" #endif #endif /* Now in `load-suffixes' definition */ #ifdef HAVE_LTDL Vload_suffixes = list3 (build_pure_c_string (MODULE_SUFFIX), build_pure_c_string (".elc"), build_pure_c_string (".el")); #else Vload_suffixes = list2 (build_pure_c_string (".elc"), build_pure_c_string (".el")); #endif I'm not familiar enough with every system but having only one extension per system is maybe limiting. After a quick search I found that Mac OSX use both .so and .dylib. Another solution would be to define a new Lisp variable `load-module-suffixes' with every possible module extensions (system specific or not) and use that to test if a file is a module or not. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-10 15:05 ` Aurélien Aptel @ 2014-10-10 15:50 ` Eli Zaretskii 2014-10-10 18:42 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2014-10-10 15:50 UTC (permalink / raw) To: Aurélien Aptel; +Cc: emacs-devel > Date: Fri, 10 Oct 2014 17:05:06 +0200 > From: Aurélien Aptel <aurelien.aptel+emacs@gmail.com> > Cc: Emacs development discussions <emacs-devel@gnu.org> > > On Thu, Oct 9, 2014 at 7:27 PM, Eli Zaretskii <eliz@gnu.org> wrote: > > Well, how about removing this issue by using lt_dlopenext? > > I use the .so extension to know whether a file is a binary module or > elisp (compiled or source). You cannot know that by the extension alone, anyway. It's unreliable. So that problem cannot be solved by using the extension explicitly. > I'm not familiar enough with every system but having only one > extension per system is maybe limiting. Emacs can use a list of extensions, not just a single extension. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-10 15:50 ` Eli Zaretskii @ 2014-10-10 18:42 ` Stefan Monnier 2014-10-10 19:58 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2014-10-10 18:42 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Aurélien Aptel, emacs-devel >> I use the .so extension to know whether a file is a binary module or >> elisp (compiled or source). > You cannot know that by the extension alone, anyway. Of course, we can: if the extension says ".el" or ".elc" we know it's Elisp (compiled or not), and if it says ".dll", ".so" or something like that, we know it's a binary module. > It's unreliable. If the user wants to use ".so" on an Elisp module, she'll get what she paid for. I'm really not worried. >> I'm not familiar enough with every system but having only one >> extension per system is maybe limiting. > Emacs can use a list of extensions, not just a single extension. Yes, it's really easy to fix. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-10 18:42 ` Stefan Monnier @ 2014-10-10 19:58 ` Eli Zaretskii 2014-10-11 5:14 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2014-10-10 19:58 UTC (permalink / raw) To: Stefan Monnier; +Cc: aurelien.aptel+emacs, emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: Aurélien Aptel <aurelien.aptel+emacs@gmail.com>, > emacs-devel@gnu.org > Date: Fri, 10 Oct 2014 14:42:56 -0400 > > >> I use the .so extension to know whether a file is a binary module or > >> elisp (compiled or source). > > You cannot know that by the extension alone, anyway. > > Of course, we can: if the extension says ".el" or ".elc" we know it's > Elisp (compiled or not), and if it says ".dll", ".so" or something like > that, we know it's a binary module. That's until you bump into a maliciously named file. > > It's unreliable. > > If the user wants to use ".so" on an Elisp module, she'll get what she > paid for. I'm really not worried. You don't have to, because loading a shared library will validate it anyway. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-10 19:58 ` Eli Zaretskii @ 2014-10-11 5:14 ` Stefan Monnier 2014-10-13 17:46 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2014-10-11 5:14 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, emacs-devel >> >> I use the .so extension to know whether a file is a binary module or >> >> elisp (compiled or source). >> > You cannot know that by the extension alone, anyway. >> Of course, we can: if the extension says ".el" or ".elc" we know it's >> Elisp (compiled or not), and if it says ".dll", ".so" or something like >> that, we know it's a binary module. > That's until you bump into a maliciously named file. I don't think it matters: the same problem can happen by playing with file's contents rather than file names. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-11 5:14 ` Stefan Monnier @ 2014-10-13 17:46 ` Aurélien Aptel 2014-10-14 18:11 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2014-10-13 17:46 UTC (permalink / raw) To: Stefan Monnier; +Cc: Eli Zaretskii, Emacs development discussions I'm with Stefan, I will make a new `load-module-suffixes' variable. Let's not turn this into a bikeshed discussion. I would like to hear your comments/feedback/ideas on the points I mentioned in my previous announcement: - should we provide a destructor mechanism in the GC? - should we add a new generic lisp type for opaque pointers? - how should modules be packaged? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-13 17:46 ` Aurélien Aptel @ 2014-10-14 18:11 ` Stefan Monnier 2014-10-16 23:09 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2014-10-14 18:11 UTC (permalink / raw) To: Aurélien Aptel; +Cc: Eli Zaretskii, Emacs development discussions > - should we provide a destructor mechanism in the GC? You mean "finalizers"? Sounds fine, yes. The GC code already has code that does similar things to handle various kinds of "weak" pointers. > - should we add a new generic lisp type for opaque pointers? Fine by me, yes. > - how should modules be packaged? As GNU ELPA packages, of course. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-14 18:11 ` Stefan Monnier @ 2014-10-16 23:09 ` Aurélien Aptel 2014-10-17 0:32 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2014-10-16 23:09 UTC (permalink / raw) To: Stefan Monnier; +Cc: Eli Zaretskii, Emacs development discussions On Tue, Oct 14, 2014 at 8:11 PM, Stefan Monnier <monnier@iro.umontreal.ca> wrote: >> - should we provide a destructor mechanism in the GC? > > You mean "finalizers"? Sounds fine, yes. The GC code already has code > that does similar things to handle various kinds of "weak" pointers. I will look into it, thanks. >> - should we add a new generic lisp type for opaque pointers? > > Fine by me, yes. Ok. I think this new type needs an unique module identifier field in order to differentiate one module type from another (per-module type predicates). This field can be a random int, it can be computed from the module struct directly, a short fixed size string (eg the module name + version), the opaque type size, or a mix of all of these... (I'm thinking out loud) >> - how should modules be packaged? > > As GNU ELPA packages, of course. Several headers are needed in order to build a module, and they have to be the one your current Emacs was built with (eg config.h). I think this means Emacs should copy those in the system include dir when installing. Can we generate a config.h from a built emacs binary? Also the whole thing has to be portable (build commands, paths, ...). Well it's going to be a nightmare to get right. In the mean time I wrote a basic YAML parsing module [1] using libyaml. You can read yaml from a file, a buffer or a string. I've tried to use direct access to lisp types (string, buffer) when reading yaml streams to prevent too much copying/type conversion overhead. I haven't done much error checking yet so it's not very robust but it works: (require 'yaml) (yaml-parse-string "--- invoice: 34843 date : 2001-01-23 bill-to: &id001 given : Chris family : Dumars address: lines: | 458 Walkman Dr. Suite #292 city : Royal Oak state : MI postal : 48046 ship-to: *id001 ") => (#s(hash-table data ("invoice" "34843" "date" "2001-01-23" "bill-to" #s(hash-table data ("given" "Chris" "family" "Dumars" "address" #s(hash-table data ("lines" "458 Walkman Dr.\nSuite #292\n" "city" "Royal Oak" "state" "MI" "postal" "48046")))) "ship-to" #s(hash-table data ("given" "Chris" "family" "Dumars" "address" #s(hash-table data ("lines" "458 Walkman Dr.\nSuite #292\n" "city" "Royal Oak" "state" "MI" "postal" "48046"))))))) (I have edited the output to make it more readable) 1: https://github.com/aaptel/emacs-dynamic-module/blob/master/modules/yaml/yaml.c ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-16 23:09 ` Aurélien Aptel @ 2014-10-17 0:32 ` Stefan Monnier 2014-10-18 21:06 ` Stephen Leake 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2014-10-17 0:32 UTC (permalink / raw) To: Aurélien Aptel; +Cc: Eli Zaretskii, Emacs development discussions > Ok. I think this new type needs an unique module identifier field in > order to differentiate one module type from another (per-module type > predicates). It might make more sense to have a "type" field which holds a Lisp_Object so we can trivially make it unique by using an object that we just allocated. >>> - how should modules be packaged? >> As GNU ELPA packages, of course. > Several headers are needed in order to build a module, and they have > to be the one your current Emacs was built with (eg config.h). Right, those headers need to be provided by Emacs. > I think this means Emacs should copy those in the system include dir > when installing. If we let Emacs run the C compiler, it can trivially add the -I args to specify where those headers are found. This way they don't need to be installed in the system's include dir (which is always a problem for non-root users, and makes it more tricky to handle multiple installs of different Emacs versions). > Can we generate a config.h from a built emacs binary? I don't think so. But we can copy the config.h (and whichever other include file we might need) when installing Emacs. > Also the whole thing has to be portable (build commands, paths, > ...). Well it's going to be a nightmare to get right. Yup! > In the mean time I wrote a basic YAML parsing module [1] using > libyaml. You can read yaml from a file, a buffer or a string. > I've tried to use direct access to lisp types (string, buffer) when > reading yaml streams to prevent too much copying/type conversion > overhead. I haven't done much error checking yet so it's not very > robust but it works: Yay! Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-17 0:32 ` Stefan Monnier @ 2014-10-18 21:06 ` Stephen Leake 0 siblings, 0 replies; 765+ messages in thread From: Stephen Leake @ 2014-10-18 21:06 UTC (permalink / raw) To: emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: >>>> - how should modules be packaged? >>> As GNU ELPA packages, of course. >> Several headers are needed in order to build a module, and they have >> to be the one your current Emacs was built with (eg config.h). > > Right, those headers need to be provided by Emacs. > >> I think this means Emacs should copy those in the system include dir >> when installing. > > If we let Emacs run the C compiler, it can trivially add the -I args > to specify where those headers are found. This way they don't need to > be installed in the system's include dir (which is always a problem for > non-root users, and makes it more tricky to handle multiple installs of > different Emacs versions). Let's not assume C; I'm planning on writing a module in Ada, with a Makefile and Ada compiler config files. One step in the Makefile will be to generate Ada import headers from the C headers, so I do still need those headers. Another module I'm planning will have texinfo sources; that needs to run 'makeinfo'. It would be excellent if 'package install' could run an arbitrary script, assuming the user has the required tools on PATH. (It would also be nice if the script gave good error messages about missing tools, but that's not Emacs's problem). Emacs could export an environment variable (or more than one) providing the location of the Emacs C headers. Perhaps the package meta information could specify whether to run gcc with -I, or to run an arbitrary build script with environment vars. Just requiring that a compiler be installed will put off a large number of users, so a binary distribution would be nice. For binary distributions, or sources with lots of other dependencies, an option is to provide the non-elisp code as an OS package thru the standard OS distribution mechanisms. Debian and Mingw64 packages would cover a lot of users (although I have some using Mac; I know nothing about packaging on Mac, except it seems to be harder than anywhere else). Then the ELPA module can list that as a dependency, and simply tell the user to install it outside Emacs if the package load fails. Or the package build script mentioned above could invoke the appropriate OS install commands. The OS distribution mechanisms have a lot of support for building things; let's not reinvent that wheel. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-10-09 17:08 ` Aurélien Aptel 2014-10-09 17:11 ` Aurélien Aptel 2014-10-09 17:27 ` Eli Zaretskii @ 2014-12-27 21:57 ` Stephen Leake 2015-01-13 14:28 ` Ted Zlatanov 2 siblings, 1 reply; 765+ messages in thread From: Stephen Leake @ 2014-12-27 21:57 UTC (permalink / raw) To: emacs-devel Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: > # build emacs > $ git clone https://github.com/aaptel/emacs-dynamic-module.git emacs-dyn > $ cd emacs-dyn > $ ./autogen.sh > $ ./configure > $ make > > # build all the modules > $ for i in modules/*; do make -C "$i"; done What happened to the 'modules' directory? It's no longer in this repository (I just cloned it), and it's not in the Savannah dynamics-modules* branches either. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2014-12-27 21:57 ` Stephen Leake @ 2015-01-13 14:28 ` Ted Zlatanov 2015-01-13 15:39 ` Stephen Leake 2015-01-17 0:10 ` Stephen Leake 0 siblings, 2 replies; 765+ messages in thread From: Ted Zlatanov @ 2015-01-13 14:28 UTC (permalink / raw) To: emacs-devel On Sat, 27 Dec 2014 15:57:05 -0600 Stephen Leake <stephen_leake@stephe-leake.org> wrote: SL> Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: >> # build emacs >> $ git clone https://github.com/aaptel/emacs-dynamic-module.git emacs-dyn >> $ cd emacs-dyn >> $ ./autogen.sh >> $ ./configure >> $ make >> >> # build all the modules >> $ for i in modules/*; do make -C "$i"; done SL> What happened to the 'modules' directory? SL> It's no longer in this repository (I just cloned it), and it's not in SL> the Savannah dynamics-modules* branches either. Aurelien asked for more time to deal with some minor issues, but the branch dynamic-modules-rc2 definitely has that directory. It just needs rebasing and testing. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-01-13 14:28 ` Ted Zlatanov @ 2015-01-13 15:39 ` Stephen Leake 2015-01-17 0:10 ` Stephen Leake 1 sibling, 0 replies; 765+ messages in thread From: Stephen Leake @ 2015-01-13 15:39 UTC (permalink / raw) To: emacs-devel Ted Zlatanov <tzz@lifelogs.com> writes: > On Sat, 27 Dec 2014 15:57:05 -0600 Stephen Leake <stephen_leake@stephe-leake.org> wrote: > > SL> Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: >>> # build emacs >>> $ git clone https://github.com/aaptel/emacs-dynamic-module.git emacs-dyn >>> $ cd emacs-dyn >>> $ ./autogen.sh >>> $ ./configure >>> $ make >>> >>> # build all the modules >>> $ for i in modules/*; do make -C "$i"; done > > SL> What happened to the 'modules' directory? > > SL> It's no longer in this repository (I just cloned it), and it's not in > SL> the Savannah dynamics-modules* branches either. > > Aurelien asked for more time to deal with some minor issues, but the > branch dynamic-modules-rc2 definitely has that directory. I had some git misunderstandings trying to checkout a separate workspace for this branch. I see it now, thanks. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-01-13 14:28 ` Ted Zlatanov 2015-01-13 15:39 ` Stephen Leake @ 2015-01-17 0:10 ` Stephen Leake 2015-01-31 18:57 ` Aurélien Aptel 1 sibling, 1 reply; 765+ messages in thread From: Stephen Leake @ 2015-01-17 0:10 UTC (permalink / raw) To: emacs-devel Ted Zlatanov <tzz@lifelogs.com> writes: > On Sat, 27 Dec 2014 15:57:05 -0600 Stephen Leake <stephen_leake@stephe-leake.org> wrote: > > SL> Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: >>> # build emacs >>> $ git clone https://github.com/aaptel/emacs-dynamic-module.git emacs-dyn >>> $ cd emacs-dyn >>> $ ./autogen.sh >>> $ ./configure >>> $ make >>> >>> # build all the modules >>> $ for i in modules/*; do make -C "$i"; done > > SL> What happened to the 'modules' directory? > > SL> It's no longer in this repository (I just cloned it), and it's not in > SL> the Savannah dynamics-modules* branches either. > > Aurelien asked for more time to deal with some minor issues, but the > branch dynamic-modules-rc2 definitely has that directory. It just needs > rebasing and testing. I rebased to master as of a couple days ago. I'm getting a compilation error: ./temacs --batch --load loadup bootstrap Loading loadup.el (source)... Using load-path (c:/Projects/emacs/dynamic-modules-rc2/lisp c:/Projects/emacs/dynamic-modules-rc2/lisp/emacs-lisp c:/Projects/emacs/dynamic-modules-rc2/lisp/language c:/Projects/emacs/dynamic-modules-rc2/lisp/international c:/Projects/emacs/dynamic-modules-rc2/lisp/textmodes c:/Projects/emacs/dynamic-modules-rc2/lisp/vc) Loading emacs-lisp/byte-run (source)... Loading emacs-lisp/backquote (source)... Symbol's function definition is void: defun Makefile:825: recipe for target 'bootstrap-emacs.exe' failed make[1]: *** [bootstrap-emacs.exe] Error 127 make[1]: Leaving directory '/c/Projects/emacs/dynamic-modules-rc2/src' Makefile:398: recipe for target 'src' failed make: *** [src] Error 2 I got the same error before the rebase. I'm building on Mingw64; I'll try on Debian. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-01-17 0:10 ` Stephen Leake @ 2015-01-31 18:57 ` Aurélien Aptel 2015-01-31 19:30 ` Eli Zaretskii 2015-02-04 12:11 ` Ted Zlatanov 0 siblings, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-01-31 18:57 UTC (permalink / raw) To: Stephen Leake; +Cc: Emacs development discussions Hi! I'm just letting everyone know I'm working on my patch again. I've started by merging the last 2-3 months commits in master but of course there are merge conflicts... It's taking more time to resolve than anticipated. There's a macro conflict with "Qc". I had to rename Qc to Qc_ in modules/opaque/opaque.c because globals.h defines Qc to something. I'm also working on a small test suite since I (and maintainers) quickly want to know when my code breaks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-01-31 18:57 ` Aurélien Aptel @ 2015-01-31 19:30 ` Eli Zaretskii 2015-02-04 21:58 ` Aurélien Aptel 2015-02-04 12:11 ` Ted Zlatanov 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-01-31 19:30 UTC (permalink / raw) To: Aurélien Aptel; +Cc: stephen_leake, emacs-devel > Date: Sat, 31 Jan 2015 19:57:42 +0100 > From: Aurélien Aptel <aurelien.aptel+emacs@gmail.com> > Cc: Emacs development discussions <emacs-devel@gnu.org> > > There's a macro conflict with "Qc". I had to rename Qc to Qc_ in > modules/opaque/opaque.c because globals.h defines Qc to something. Most probably, that's not the right solution. You should instead refrain from declaring Qc, since make-doc and globals.h now take care of that. See how other Q* symbols are defined and declared. Thanks for your work. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-01-31 19:30 ` Eli Zaretskii @ 2015-02-04 21:58 ` Aurélien Aptel 2015-02-04 22:03 ` Aurélien Aptel ` (2 more replies) 0 siblings, 3 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-02-04 21:58 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stephen Leake, Emacs development discussions On Sat, Jan 31, 2015 at 8:30 PM, Eli Zaretskii <eliz@gnu.org> wrote: > Most probably, that's not the right solution. You should instead > refrain from declaring Qc, since make-doc and globals.h now take care > of that. See how other Q* symbols are defined and declared. You can't expect modules to keep up with core global variables. At least not for such generic, short variables which shouldn't be global in the first place. What do you think? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-04 21:58 ` Aurélien Aptel @ 2015-02-04 22:03 ` Aurélien Aptel 2015-02-05 0:24 ` Stephen J. Turnbull 2015-02-05 3:50 ` Eli Zaretskii 2 siblings, 0 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-02-04 22:03 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stephen Leake, Emacs development discussions The next thing I will work on is the new module Lisp_Object type and the custom destructor mechanism for it in the GC. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-04 21:58 ` Aurélien Aptel 2015-02-04 22:03 ` Aurélien Aptel @ 2015-02-05 0:24 ` Stephen J. Turnbull 2015-02-05 3:50 ` Eli Zaretskii 2 siblings, 0 replies; 765+ messages in thread From: Stephen J. Turnbull @ 2015-02-05 0:24 UTC (permalink / raw) To: Aurélien Aptel Cc: Eli Zaretskii, Stephen Leake, Emacs development discussions Aurélien Aptel writes: > You can't expect modules to keep up with core global variables. No, you can't. You *can*, however, expect modules to maintain proper namespace hygiene for *symbols*. And *must*: this is the Land of (Emacs) Lisp, where symbols are all global. > At least not for such generic, short variables which shouldn't be > global in the first place. What do you think? I think `Fintern' is your friend. That has worked in XEmacs for the last 15 years. I don't see why it won't work in Emacs. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-04 21:58 ` Aurélien Aptel 2015-02-04 22:03 ` Aurélien Aptel 2015-02-05 0:24 ` Stephen J. Turnbull @ 2015-02-05 3:50 ` Eli Zaretskii 2015-02-09 0:04 ` Aurélien Aptel 2 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-05 3:50 UTC (permalink / raw) To: Aurélien Aptel; +Cc: stephen_leake, emacs-devel > Date: Wed, 4 Feb 2015 22:58:08 +0100 > From: Aurélien Aptel <aurelien.aptel+emacs@gmail.com> > Cc: Stephen Leake <stephen_leake@stephe-leake.org>, > Emacs development discussions <emacs-devel@gnu.org> > > On Sat, Jan 31, 2015 at 8:30 PM, Eli Zaretskii <eliz@gnu.org> wrote: > > Most probably, that's not the right solution. You should instead > > refrain from declaring Qc, since make-doc and globals.h now take care > > of that. See how other Q* symbols are defined and declared. > > You can't expect modules to keep up with core global variables. At > least not for such generic, short variables which shouldn't be global > in the first place. What do you think? I thought figuring out how to solve this is part of the job. Modules will not really be workable unless this issue is resolved in a way that doesn't break them with every change in the core. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-05 3:50 ` Eli Zaretskii @ 2015-02-09 0:04 ` Aurélien Aptel 2015-02-09 0:34 ` Paul Eggert 2015-02-10 14:56 ` Ted Zlatanov 0 siblings, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-02-09 0:04 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stephen Leake, Emacs development discussions Ok, what I've pushed on my branch is now working. For some reasons, DEFSYM was a no-op in module code so I've replaced DEFSYM calls with: MQfoo = intern ("foo") Are there any drawbacks? On Thu, Feb 5, 2015 at 4:50 AM, Eli Zaretskii <eliz@gnu.org> wrote: > I thought figuring out how to solve this is part of the job. Modules > will not really be workable unless this issue is resolved in a way > that doesn't break them with every change in the core. I've settled for a M prefix on all global module variables. Well only symbols right now since that's all I'm using. The whole reason why I've put them global is because that's what the core does but as it turns out it's not needed here. The fact that globals are actually macros exanding to a global struct member is not desirable here as it prevents normal C lexical scoping. By the way, there are some conventions that I'd like to understand like prefixes: V is for lisp variables, F for functions, S for subr, Q is for symbols (Q as in Quote since S was taken?). Am I missing something? One last thing, I need a deep `equal' function that also works hash-tables (every key and values must be equal) in yaml/test.el to compare nested lisp objects. Do I need to hand roll this myself? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-09 0:04 ` Aurélien Aptel @ 2015-02-09 0:34 ` Paul Eggert 2015-02-09 4:17 ` Stefan Monnier 2015-02-10 14:56 ` Ted Zlatanov 1 sibling, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-02-09 0:34 UTC (permalink / raw) To: Aurélien Aptel, Eli Zaretskii Cc: Stephen Leake, Emacs development discussions Aurélien Aptel wrote: > I've replaced > DEFSYM calls with: > > MQfoo = intern ("foo") > > Are there any drawbacks? It's a bit slower. Symbols like Qabove are compile-time constants; on my platform, for example, Qabove == 8688, and this integer is known at compile-time. This gives C compilers more opportunities for optimization than variables like MQfoo do. > The fact that > globals are actually macros exanding to a global struct member is not > desirable here as it prevents normal C lexical scoping. That sounds like it might be more trouble than it's worth. These symbols are globally unique anyway, in Elisp, so it's a bit clearer to keep them globally unique in C as well, rather than attempt to reuse them with C lexical scoping. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-09 0:34 ` Paul Eggert @ 2015-02-09 4:17 ` Stefan Monnier 2015-02-09 6:26 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-02-09 4:17 UTC (permalink / raw) To: Paul Eggert Cc: Aurélien Aptel, Eli Zaretskii, Stephen Leake, Emacs development discussions > Aurélien Aptel wrote: >> I've replaced >> DEFSYM calls with: >> MQfoo = intern ("foo") >> Are there any drawbacks? That looks good. > It's a bit slower. Symbols like Qabove are compile-time constants; on my > platform, for example, Qabove == 8688, and this integer is known at > compile-time. This gives C compilers more opportunities for optimization > than variables like MQfoo do. But he's talking about code in plugins, i.e. code which needs to be compiled seaprately from Emacs itself and where the .(s)o file needs to be re-usable with several different Emacs executables, so the special optimization as used for Qabove is not an option. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-09 4:17 ` Stefan Monnier @ 2015-02-09 6:26 ` Paul Eggert 2015-02-09 9:58 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-02-09 6:26 UTC (permalink / raw) To: Stefan Monnier Cc: Aurélien Aptel, Eli Zaretskii, Stephen Leake, Emacs development discussions Stefan Monnier wrote: > he's talking about code in plugins, i.e. code which needs to be > compiled seaprately from Emacs itself and where the .(s)o file needs to > be re-usable with several different Emacs executables First, in that case the value of Qabove is known at link-time, and compilers should be able to do a better job with link-time constants than with variables. Second, even plugins can be subject to link-time optimization, if one's linker is smart enough, as gold is. I hadn't considered either of these possibilities when adding the lispsym support, so Aurélien's approach of calling 'intern' is the best we can do now. However, I suggest packaging those calls into a function ('module_defsym', say?) so that its implementation can be improved later, if someone wants to work on that. One other thing: I don't see the point of prefixing global module symbols with 'MQ' as opposed to 'Q'. Users of these symbols shouldn't care whether a module defined them, or the core interpreter defined them. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-09 6:26 ` Paul Eggert @ 2015-02-09 9:58 ` Aurélien Aptel 2015-02-09 15:45 ` Eli Zaretskii 2015-02-10 6:58 ` Paul Eggert 0 siblings, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-02-09 9:58 UTC (permalink / raw) To: Paul Eggert Cc: Eli Zaretskii, Stephen Leake, Stefan Monnier, Emacs development discussions On Mon, Feb 9, 2015 at 7:26 AM, Paul Eggert <eggert@cs.ucla.edu> wrote: > One other thing: I don't see the point of prefixing global module symbols > with 'MQ' as opposed to 'Q'. Users of these symbols shouldn't care whether > a module defined them, or the core interpreter defined them. Global vars in core end up as macros. I was using Qc in the opaque module but it broke recently when core defined it too. Since it's hard to keep up with what core defines, adding a prefix prevents the clash. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-09 9:58 ` Aurélien Aptel @ 2015-02-09 15:45 ` Eli Zaretskii 2015-02-09 16:01 ` Aurélien Aptel 2015-02-10 6:58 ` Paul Eggert 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-09 15:45 UTC (permalink / raw) To: Aurélien Aptel; +Cc: eggert, stephen_leake, monnier, emacs-devel > Date: Mon, 9 Feb 2015 10:58:55 +0100 > From: Aurélien Aptel <aurelien.aptel+emacs@gmail.com> > Cc: Stefan Monnier <monnier@iro.umontreal.ca>, Eli Zaretskii <eliz@gnu.org>, > Stephen Leake <stephen_leake@stephe-leake.org>, > Emacs development discussions <emacs-devel@gnu.org> > > I was using Qc in the opaque module but it broke recently when core > defined it too. Can you explain why your Qc was globally visible? Can't you arrange for it to remain un-exported? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-09 15:45 ` Eli Zaretskii @ 2015-02-09 16:01 ` Aurélien Aptel 0 siblings, 0 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-02-09 16:01 UTC (permalink / raw) To: Eli Zaretskii Cc: Paul Eggert, Stephen Leake, Stefan Monnier, Emacs development discussions On Mon, Feb 9, 2015 at 4:45 PM, Eli Zaretskii <eliz@gnu.org> wrote: > Can you explain why your Qc was globally visible? Can't you arrange > for it to remain un-exported? I thought it was a convention? See one of my previous message. Anyway it doesn't matter if it's global: Qc expands to a member of a struct. No matter where I declare Qc in my module, the preprocessor will expand it into something invalid. I'm not actually sure what it expands to right now, I'm at work now and I can't test it. Any existing solutions for the hash-table equality test I was talking about earlier? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-09 9:58 ` Aurélien Aptel 2015-02-09 15:45 ` Eli Zaretskii @ 2015-02-10 6:58 ` Paul Eggert 2015-02-10 20:40 ` Stefan Monnier 2015-02-11 9:19 ` Aurélien Aptel 1 sibling, 2 replies; 765+ messages in thread From: Paul Eggert @ 2015-02-10 6:58 UTC (permalink / raw) To: Aurélien Aptel; +Cc: Stephen Leake, Emacs development discussions Aurélien Aptel wrote: > Since it's hard to keep up with what core defines, adding a prefix > prevents the clash. Ah, OK, that explains things. Though this raises a related issue: as I understand it currently modules must never refer to any Qxxx symbols (other than Qnil), since these symbols may have different values in different Emacs implementations. And this includes any macros or inline functions the modules may invoke. For example, a module must never call 'functionp', since 'functionp' is an inline function that refers to Qt. This is something that needs to be fixed, surely. And once we have a fix for it, perhaps the fix will mean that we don't need that "M" prefix. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-10 6:58 ` Paul Eggert @ 2015-02-10 20:40 ` Stefan Monnier 2015-02-10 22:24 ` Paul Eggert 2015-02-11 9:19 ` Aurélien Aptel 1 sibling, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-02-10 20:40 UTC (permalink / raw) To: Paul Eggert Cc: Aurélien Aptel, Stephen Leake, Emacs development discussions I think what this boils down to, is that we need a "emacs.h" or something like that which modules would include instead of including lisp.h. Stefan >>>>> "Paul" == Paul Eggert <eggert@cs.ucla.edu> writes: > Aurélien Aptel wrote: >> Since it's hard to keep up with what core defines, adding a prefix >> prevents the clash. > Ah, OK, that explains things. > Though this raises a related issue: as I understand it currently modules > must never refer to any Qxxx symbols (other than Qnil), since these symbols > may have different values in different Emacs implementations. And this > includes any macros or inline functions the modules may invoke. > For example, a module must never call 'functionp', since 'functionp' is an > inline function that refers to Qt. > This is something that needs to be fixed, surely. And once we have a fix > for it, perhaps the fix will mean that we don't need that "M" prefix. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-10 20:40 ` Stefan Monnier @ 2015-02-10 22:24 ` Paul Eggert 2015-02-11 1:45 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-02-10 22:24 UTC (permalink / raw) To: Stefan Monnier Cc: Aurélien Aptel, Stephen Leake, Emacs development discussions On 02/10/2015 12:40 PM, Stefan Monnier wrote: > I think what this boils down to, is that we need a "emacs.h" or > something like that which modules would include instead of including > lisp.h. Yes, I was thinking of something along those lines as well. "emacs.h" could, for example, define a symbol EMACS_MODULE that is 1 (whereas it's 0 for core Emacs code), and then globals.h could conditionally define Qxxx to be something that's dynamically linkable but slower if EMACS_MODULE is 1, and to be something that's not dynamically linkable but faster if EMACS_MODULE is 0. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-10 22:24 ` Paul Eggert @ 2015-02-11 1:45 ` Stefan Monnier 2015-02-11 15:36 ` Ted Zlatanov 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-02-11 1:45 UTC (permalink / raw) To: Paul Eggert Cc: Aurélien Aptel, Stephen Leake, Emacs development discussions >> I think what this boils down to, is that we need a "emacs.h" or >> something like that which modules would include instead of including >> lisp.h. > Yes, I was thinking of something along those lines as well. "emacs.h" could, > for example, define a symbol EMACS_MODULE that is 1 (whereas it's 0 for core > Emacs code), and then globals.h could conditionally define Qxxx to be > something that's dynamically linkable but slower if EMACS_MODULE is 1, and > to be something that's not dynamically linkable but faster if EMACS_MODULE > is 0. I was thinking of making emacs.h a "real file" which would contain a subset of the current lisp.h and then lisp.h would #include it. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-11 1:45 ` Stefan Monnier @ 2015-02-11 15:36 ` Ted Zlatanov 2015-02-13 2:40 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Ted Zlatanov @ 2015-02-11 15:36 UTC (permalink / raw) To: emacs-devel On Tue, 10 Feb 2015 20:45:03 -0500 Stefan Monnier <monnier@IRO.UMontreal.CA> wrote: SM> I was thinking of making emacs.h a "real file" which would contain SM> a subset of the current lisp.h and then lisp.h would #include it. On Wed, 11 Feb 2015 05:26:12 -0800 Paul Eggert <eggert@cs.ucla.edu> wrote: PE> you start your module this way: PE> #define EMACS_MODULE PE> #include <lisp.h> PE> or better, we package up an <emacs.h> file the way Stefan suggested. I'd love to see emacs.h become a real API for modules. But `#define EMACS_MODULE' is a good idea regardless, for cleanliness. I would even define it to be "1.0" to indicate module version 1 (the initial). Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-11 15:36 ` Ted Zlatanov @ 2015-02-13 2:40 ` Paul Eggert 2015-02-13 8:37 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-02-13 2:40 UTC (permalink / raw) To: emacs-devel To help make progress on the plugin compatibility issue I installed commit 65563fd7714271582d5146c09202c0f7a0631fe5 in the master. A plugin should do this: #define DEFINE_NONNIL_Q_SYMBOL_MACROS false before including globals.h either directly or indirectly. This #define could be part of any new emacs.h. We're not out of the woods yet, I'm afraid. For example, suppose a new version of Emacs adds a new kind of function, and that the implementation of functionp changes. And suppose a plugin is compiled with the old version of Emacs and uses the FUNCTIONP macro. Since FUNCTIONP's expansion calls functionp and functionp is an extern inline function, the plugin may use the old version of functionp or it may use the new one -- the C standard allows either behavior. Either way, the plugin may misbehave. This sort of thing suggests that it may be difficult to guarantee upward compatibility of plugins from one version of Emacs to the next. And perhaps we shouldn't even try. This raises another question: what exactly should go into emacs.h? The more we put into emacs.h, the more likely plugin compatibility won't survive the transition from one version of Emacs to the next. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 2:40 ` Paul Eggert @ 2015-02-13 8:37 ` Eli Zaretskii 2015-02-13 12:17 ` Daniel Colascione 2015-02-13 19:11 ` Stefan Monnier 0 siblings, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-02-13 8:37 UTC (permalink / raw) To: Paul Eggert; +Cc: emacs-devel > Date: Thu, 12 Feb 2015 18:40:19 -0800 > From: Paul Eggert <eggert@cs.ucla.edu> > > This raises another question: what exactly should go into emacs.h? The more we > put into emacs.h, the more likely plugin compatibility won't survive the > transition from one version of Emacs to the next. Right. emacs.h should include the bare minimum, and each function, macro, or variable we put there should have a very good reason for being there. IOW, we should design the interface between the modules and Emacs, and we should do this ASAP, before the status quo forces us to make compromises we will be unhappy with down the line. I would start by coming up with the minimum set of requirements a module needs to be able to communicate with Emacs. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 8:37 ` Eli Zaretskii @ 2015-02-13 12:17 ` Daniel Colascione 2015-02-13 15:01 ` Eli Zaretskii 2015-02-13 19:11 ` Stefan Monnier 1 sibling, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-02-13 12:17 UTC (permalink / raw) To: Eli Zaretskii, Paul Eggert; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1094 bytes --] On 02/13/2015 12:37 AM, Eli Zaretskii wrote: >> Date: Thu, 12 Feb 2015 18:40:19 -0800 >> From: Paul Eggert <eggert@cs.ucla.edu> >> >> This raises another question: what exactly should go into emacs.h? The more we >> put into emacs.h, the more likely plugin compatibility won't survive the >> transition from one version of Emacs to the next. > > Right. emacs.h should include the bare minimum, and each function, > macro, or variable we put there should have a very good reason for > being there. > > IOW, we should design the interface between the modules and Emacs, and > we should do this ASAP, before the status quo forces us to make > compromises we will be unhappy with down the line. That's why this whole module effort is misguided and dangerous. With a CFFI-style approach to loading code dynamically, shared modules don't need to know anything about Emacs internal structure, so there are no ABI or source compatibility issues. I still think a CFFI port would be less work than trying to extract a stable Emacs internals API that modules can include. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 12:17 ` Daniel Colascione @ 2015-02-13 15:01 ` Eli Zaretskii 2015-02-13 15:06 ` Daniel Colascione 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-13 15:01 UTC (permalink / raw) To: Daniel Colascione; +Cc: eggert, emacs-devel > Date: Fri, 13 Feb 2015 04:17:17 -0800 > From: Daniel Colascione <dancol@dancol.org> > CC: emacs-devel@gnu.org > > That's why this whole module effort is misguided and dangerous. With a > CFFI-style approach to loading code dynamically, shared modules don't > need to know anything about Emacs internal structure, so there are no > ABI or source compatibility issues. > > I still think a CFFI port would be less work than trying to extract a > stable Emacs internals API that modules can include. I don't understand how CFFI would solve the problem, at least not all of it. We'd still need to write code to allow modules create Lisp objects, right? That code would still be Emacs version dependent, right? What am I missing? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 15:01 ` Eli Zaretskii @ 2015-02-13 15:06 ` Daniel Colascione 2015-02-13 15:49 ` Eli Zaretskii 2015-02-13 21:48 ` Stephen Leake 0 siblings, 2 replies; 765+ messages in thread From: Daniel Colascione @ 2015-02-13 15:06 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1544 bytes --] On 02/13/2015 07:01 AM, Eli Zaretskii wrote: >> Date: Fri, 13 Feb 2015 04:17:17 -0800 >> From: Daniel Colascione <dancol@dancol.org> >> CC: emacs-devel@gnu.org >> >> That's why this whole module effort is misguided and dangerous. With a >> CFFI-style approach to loading code dynamically, shared modules don't >> need to know anything about Emacs internal structure, so there are no >> ABI or source compatibility issues. >> >> I still think a CFFI port would be less work than trying to extract a >> stable Emacs internals API that modules can include. > > I don't understand how CFFI would solve the problem, at least not all > of it. We'd still need to write code to allow modules create Lisp > objects, right? That code would still be Emacs version dependent, > right? What am I missing? In a CFFI world, modules don't know about lisp at all. Lisp code describes the signatures of functions in loaded modules and calls into the automatically generated wrapper functions. The called code has no idea it's being called from lisp. If native code needs to create an object, it creates it in the normal way and returns a pointer; lisp then manages that pointer as an opaque value, possibly supplying it to further calls to that module's functions. This way, instead of loaded modules needing to track Emacs' historically unstable internal data structures, elisp needs to track module ABIs, which _have_ historically been stable; elisp interfaces can also be updated without requiring users have a compiler. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 15:06 ` Daniel Colascione @ 2015-02-13 15:49 ` Eli Zaretskii 2015-02-13 15:58 ` Daniel Colascione 2015-02-13 21:48 ` Stephen Leake 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-13 15:49 UTC (permalink / raw) To: Daniel Colascione; +Cc: eggert, emacs-devel > Date: Fri, 13 Feb 2015 07:06:17 -0800 > From: Daniel Colascione <dancol@dancol.org> > CC: eggert@cs.ucla.edu, emacs-devel@gnu.org > > This way, instead of loaded modules needing to track Emacs' historically > unstable internal data structures, elisp needs to track module ABIs, How's that better? That's the same problem in the opposite direction, only much worse, since the modules out there are not under our control at all. Maybe it works in Python because Python is much more standardized and stable that Emacs Lisp. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 15:49 ` Eli Zaretskii @ 2015-02-13 15:58 ` Daniel Colascione 2015-02-13 16:10 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-02-13 15:58 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1385 bytes --] On 02/13/2015 07:49 AM, Eli Zaretskii wrote: >> Date: Fri, 13 Feb 2015 07:06:17 -0800 >> From: Daniel Colascione <dancol@dancol.org> >> CC: eggert@cs.ucla.edu, emacs-devel@gnu.org >> >> This way, instead of loaded modules needing to track Emacs' historically >> unstable internal data structures, elisp needs to track module ABIs, > > How's that better? That's the same problem in the opposite direction, > only much worse, since the modules out there are not under our control > at all. The risk isn't symmetric: 1) Shared libraries traditionally expose stable ABIs; when ABIs change incompatibly, libraries change sonames. Shared libraries need stable ABIs whether or not Emacs loads them: they're linked into other programs and aren't necessarily rebuilt at the same time as their dependencies. The Emacs core has never had a stable ABI, and creating one would constrain our optimization opportunities. (That is, libpng.so's ABI ought to change a lot less often than /usr/bin/emacs's: the former promises to provide a stable ABI and the latter never has.) 2) If a shared library's ABI does change, a Lisp update can fix the problem. On the other hand, if a strongly-coupled module becomes incompatible with the Emacs core, the remedy involves recompiling either Emacs or the module. It's much easier to update Lisp than to rebuild native code. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 15:58 ` Daniel Colascione @ 2015-02-13 16:10 ` Eli Zaretskii 2015-02-13 16:20 ` Daniel Colascione 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-13 16:10 UTC (permalink / raw) To: Daniel Colascione; +Cc: eggert, emacs-devel > Date: Fri, 13 Feb 2015 07:58:12 -0800 > From: Daniel Colascione <dancol@dancol.org> > CC: eggert@cs.ucla.edu, emacs-devel@gnu.org > > 1) Shared libraries traditionally expose stable ABIs; when ABIs change > incompatibly, libraries change sonames. Shared libraries need stable > ABIs whether or not Emacs loads them: they're linked into other programs > and aren't necessarily rebuilt at the same time as their dependencies. > The Emacs core has never had a stable ABI, and creating one would > constrain our optimization opportunities. > > (That is, libpng.so's ABI ought to change a lot less often than > /usr/bin/emacs's: the former promises to provide a stable ABI and the > latter never has.) Sorry, I don't share your optimism about the stability of their ABI. In particular, image libraries are a bad example on which to build your point: look at the versonitis we need to employ in w32-win.el to support all their different ABIs. Each new revision there breaks Emacs build with them. And we didn't yet start talking about problems with passing FILE pointers and malloc'ed buffers between Emacs and the modules. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 16:10 ` Eli Zaretskii @ 2015-02-13 16:20 ` Daniel Colascione 2015-02-13 16:55 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-02-13 16:20 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel [-- Attachment #1: Type: text/plain, Size: 2445 bytes --] On 02/13/2015 08:10 AM, Eli Zaretskii wrote: >> Date: Fri, 13 Feb 2015 07:58:12 -0800 >> From: Daniel Colascione <dancol@dancol.org> >> CC: eggert@cs.ucla.edu, emacs-devel@gnu.org >> >> 1) Shared libraries traditionally expose stable ABIs; when ABIs change >> incompatibly, libraries change sonames. Shared libraries need stable >> ABIs whether or not Emacs loads them: they're linked into other programs >> and aren't necessarily rebuilt at the same time as their dependencies. >> The Emacs core has never had a stable ABI, and creating one would >> constrain our optimization opportunities. >> >> (That is, libpng.so's ABI ought to change a lot less often than >> /usr/bin/emacs's: the former promises to provide a stable ABI and the >> latter never has.) > > Sorry, I don't share your optimism about the stability of their ABI. My optimism is rooted in reality. Most shared library interfaces are stable the vast majority of the time. If ABIs were generally unstable, we'd have to rebuild programs constantly, yet I can run very old binaries (especially on Windows) without trouble. > In particular, image libraries are a bad example on which to build > your point: look at the versonitis we need to employ in w32-win.el to > support all their different ABIs. Each new revision there breaks > Emacs build with them. w32-win.el isn't that bad, especially for a module that loads quite a few different image libraries. Besides: using modules tightly coupled to the Emacs core doesn't actually help. Instead of elisp coupled to one module's stable ABI, you have a piece of native code tightly coupled not only to that module's stable ABI, but _also_ to the volatile Emacs internal ABI. As jwz would say, now you have two problems. Using a CFFI-like approach both reduces the volatility of the interface (since now there's a strong boundary in only one direction) and makes it easier to fix problems when they do come up. > And we didn't yet start talking about problems with passing FILE > pointers and malloc'ed buffers between Emacs and the modules. You have that problem anyway: a tightly-bound Emacs module for bridging the Emacs core and some third-party library would have to link against _some_ libc, and unless both the Emacs core and the third-party library used the same libc, you'd lose. A better idea is not to pass C runtime objects between dynamically loaded components. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 16:20 ` Daniel Colascione @ 2015-02-13 16:55 ` Eli Zaretskii 2015-02-13 17:08 ` Paul Eggert 2015-02-13 17:38 ` Daniel Colascione 0 siblings, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-02-13 16:55 UTC (permalink / raw) To: Daniel Colascione; +Cc: eggert, emacs-devel > Date: Fri, 13 Feb 2015 08:20:09 -0800 > From: Daniel Colascione <dancol@dancol.org> > CC: eggert@cs.ucla.edu, emacs-devel@gnu.org > > > Sorry, I don't share your optimism about the stability of their ABI. > > My optimism is rooted in reality. So is mine. I guess our experiences differ. > w32-win.el isn't that bad, especially for a module that loads quite a > few different image libraries. It's not bad when you get it ready. But the effort it took to find out which versions changed ABI, to design the way of testing that, and to have all the #ifdef's in Emacs core to support all of those versions, and continue maintaining that as new versions arrive, is anything but trivial, take it from someone who did most of that. > Besides: using modules tightly coupled to the Emacs core doesn't > actually help. Instead of elisp coupled to one module's stable ABI, you > have a piece of native code tightly coupled not only to that module's > stable ABI, but _also_ to the volatile Emacs internal ABI. As jwz would > say, now you have two problems. No, we have only one problem: design and implement a minimal set of APIs necessary for modules to work, and keep it minimal. All the rest is the problem of module developers. It makes little sense to me to turn the table and make module compatibility something that core developers need to take care of. > > And we didn't yet start talking about problems with passing FILE > > pointers and malloc'ed buffers between Emacs and the modules. > > You have that problem anyway: a tightly-bound Emacs module for bridging > the Emacs core and some third-party library would have to link against > _some_ libc, and unless both the Emacs core and the third-party library > used the same libc, you'd lose. A well-designed set of APIs between Emacs and modules will avoid this and other similar problems. This has already been done at least twice, in 2 different ways: in Make and in Gawk. I see no reason why Emacs couldn't do something similar to one of those methods. > A better idea is not to pass C runtime objects between dynamically > loaded components. Exactly. But this requires the set of APIs I'm talking about to support this without making non-trivial modules impossible. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 16:55 ` Eli Zaretskii @ 2015-02-13 17:08 ` Paul Eggert 2015-02-13 17:44 ` Daniel Colascione 2015-02-13 17:38 ` Daniel Colascione 1 sibling, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-02-13 17:08 UTC (permalink / raw) To: Eli Zaretskii, Daniel Colascione; +Cc: emacs-devel Eli Zaretskii wrote: > A well-designed set of APIs between Emacs and modules will avoid this > and other similar problems. This has already been done at least > twice, in 2 different ways: in Make and in Gawk. Sure, but the cffi/libffi approach has seen a lot more uptake than that: GCC, CPython, OpenJDK, PLT Scheme, etc., etc. It's quite a well-trodden path. > we have only one problem: design and implement a minimal set of > APIs necessary for modules to work, and keep it minimal. cffi/libffi provides a good framework for that, no? Why reinvent the wheel? Because that's what we'd need to do, when designing this new emacs.h file. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 17:08 ` Paul Eggert @ 2015-02-13 17:44 ` Daniel Colascione 2015-02-13 19:11 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-02-13 17:44 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1562 bytes --] On 02/13/2015 09:08 AM, Paul Eggert wrote: > Eli Zaretskii wrote: >> A well-designed set of APIs between Emacs and modules will avoid this >> and other similar problems. This has already been done at least >> twice, in 2 different ways: in Make and in Gawk. > > Sure, but the cffi/libffi approach has seen a lot more uptake than that: > GCC, CPython, OpenJDK, PLT Scheme, etc., etc. It's quite a well-trodden > path. > >> we have only one problem: design and implement a minimal set of >> APIs necessary for modules to work, and keep it minimal. > > cffi/libffi provides a good framework for that, no? Why reinvent the > wheel? Because that's what we'd need to do, when designing this new > emacs.h file. I was imagining emacs.h looking a lot like jni.h: modules would export some kind of emacs_init symbol that the Emacs core would call --- say, something like this: struct emacs_runtime { /* Return NULL on failure */ struct emacs_interface* (*init)( int interface_version, const char* my_license); }; struct emacs_interface_1 { /* Err, something like this */ struct emacs_value* (*defun)(const char* name, int nargs); struct emacs_value* (*funcall)(struct emacs_value* func, ...); }; /* Exported by loadable modules and called on load. Return 0 on success or -1 on error. */ extern int emacs_init(struct emacs_runtime*); This way, Emacs itself doesn't need to export any symbols and it can support multiple interface versions sanely. I'd still prefer a CFFI-style interface though. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 17:44 ` Daniel Colascione @ 2015-02-13 19:11 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-02-13 19:11 UTC (permalink / raw) To: Daniel Colascione; +Cc: eggert, emacs-devel > Date: Fri, 13 Feb 2015 09:44:47 -0800 > From: Daniel Colascione <dancol@dancol.org> > Cc: emacs-devel@gnu.org > > struct emacs_runtime { > /* Return NULL on failure */ > struct emacs_interface* (*init)( > int interface_version, > const char* my_license); > }; > > struct emacs_interface_1 { > /* Err, something like this */ > struct emacs_value* (*defun)(const char* name, int nargs); > struct emacs_value* (*funcall)(struct emacs_value* func, ...); > }; > > /* Exported by loadable modules and called on load. > Return 0 on success or -1 on error. */ > extern int emacs_init(struct emacs_runtime*); > > This way, Emacs itself doesn't need to export any symbols and it can > support multiple interface versions sanely. IOW, you suggest that the interface will be through function pointers. That's how Gawk does it. This method (and any other) will need function pointers to create Lisp data structures, though. Like strings, lists, vectors, etc. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 16:55 ` Eli Zaretskii 2015-02-13 17:08 ` Paul Eggert @ 2015-02-13 17:38 ` Daniel Colascione 1 sibling, 0 replies; 765+ messages in thread From: Daniel Colascione @ 2015-02-13 17:38 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel [-- Attachment #1: Type: text/plain, Size: 3345 bytes --] On 02/13/2015 08:55 AM, Eli Zaretskii wrote: >> Date: Fri, 13 Feb 2015 08:20:09 -0800 >> From: Daniel Colascione <dancol@dancol.org> >> CC: eggert@cs.ucla.edu, emacs-devel@gnu.org >> >>> Sorry, I don't share your optimism about the stability of their ABI. >> >> My optimism is rooted in reality. > > So is mine. I guess our experiences differ. > >> w32-win.el isn't that bad, especially for a module that loads quite a >> few different image libraries. > > It's not bad when you get it ready. But the effort it took to find > out which versions changed ABI, to design the way of testing that, and > to have all the #ifdef's in Emacs core to support all of those > versions, and continue maintaining that as new versions arrive, is > anything but trivial, take it from someone who did most of that. > >> Besides: using modules tightly coupled to the Emacs core doesn't >> actually help. Instead of elisp coupled to one module's stable ABI, you >> have a piece of native code tightly coupled not only to that module's >> stable ABI, but _also_ to the volatile Emacs internal ABI. As jwz would >> say, now you have two problems. > > No, we have only one problem: design and implement a minimal set of > APIs necessary for modules to work, and keep it minimal. All the rest > is the problem of module developers. Well, at least the proposed module design should allow the creation of a CFFI interface _on top_ of it --- a bit like how we can use Java's JNI to implement JNA. By the way: Java does it the proposed Emacs way (via JNI), and the CLR does it the way I propose (via P/Invoke). In my experience, P/Invoke-using modules have been far less painful to use and maintain than JNI-using ones. Speaking of JNI: if you insist on tightly coupling modules to the Emacs core, it's better to use a versioned system like JNI than to just dynamically export symbols from the Emacs core. This way, module A can request interface version 1 and module B can request interface version 2, and as long as a particular Emacs supports both interfaces 1 and 2, you can load both modules into the same Emacs without trouble and without rebuilding anything. > It makes little sense to me to turn the table and make module > compatibility something that core developers need to take care of. With the proposed design, core developers have to take pains to make Emacs itself export a stable ABI. With a CFFI-style interface, Emacs doesn't have to maintain a stable ABI at all. To me, that sounds like making life for core developers easier. >>> And we didn't yet start talking about problems with passing FILE >>> pointers and malloc'ed buffers between Emacs and the modules. >> >> You have that problem anyway: a tightly-bound Emacs module for bridging >> the Emacs core and some third-party library would have to link against >> _some_ libc, and unless both the Emacs core and the third-party library >> used the same libc, you'd lose. > > A well-designed set of APIs between Emacs and modules will avoid this > and other similar problems. This has already been done at least > twice, in 2 different ways: in Make and in Gawk. I see no reason why > Emacs couldn't do something similar to one of those methods. Woah. I had no idea that make supported loading dynamic objects. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 15:06 ` Daniel Colascione 2015-02-13 15:49 ` Eli Zaretskii @ 2015-02-13 21:48 ` Stephen Leake 2015-02-14 8:39 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Stephen Leake @ 2015-02-13 21:48 UTC (permalink / raw) To: emacs-devel Daniel Colascione <dancol@dancol.org> writes: > On 02/13/2015 07:01 AM, Eli Zaretskii wrote: >>> Date: Fri, 13 Feb 2015 04:17:17 -0800 >>> From: Daniel Colascione <dancol@dancol.org> >>> CC: emacs-devel@gnu.org >>> >>> That's why this whole module effort is misguided and dangerous. With a >>> CFFI-style approach to loading code dynamically, shared modules don't >>> need to know anything about Emacs internal structure, so there are no >>> ABI or source compatibility issues. >>> >>> I still think a CFFI port would be less work than trying to extract a >>> stable Emacs internals API that modules can include. >> >> I don't understand how CFFI would solve the problem, at least not all >> of it. We'd still need to write code to allow modules create Lisp >> objects, right? That code would still be Emacs version dependent, >> right? What am I missing? > > In a CFFI world, modules don't know about lisp at all. Lisp code > describes the signatures of functions in loaded modules and calls into > the automatically generated wrapper functions. The called code has no > idea it's being called from lisp. Which means (I think), that module code cannot call lisp functions. My use case requires calling lisp functions; in particular, put-text-property, but also other higher-level lisp functions in ada-mode. I need a compiled module to implement an LALR parser for the Ada language that is fast enough for very large files. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 21:48 ` Stephen Leake @ 2015-02-14 8:39 ` Eli Zaretskii 2015-02-14 12:18 ` Stephen J. Turnbull 2015-02-14 15:32 ` Stephen Leake 0 siblings, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-02-14 8:39 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel > From: Stephen Leake <stephen_leake@stephe-leake.org> > Date: Fri, 13 Feb 2015 15:48:07 -0600 > > My use case requires calling lisp functions; in particular, > put-text-property, but also other higher-level lisp functions in > ada-mode. Why do you need to call Lisp in the module? I think it's a no-no for modules to call Lisp; that should be done in the Lisp code that uses the module. > I need a compiled module to implement an LALR parser for the Ada > language that is fast enough for very large files. Why does an implementation of a parser need to call Lisp? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 8:39 ` Eli Zaretskii @ 2015-02-14 12:18 ` Stephen J. Turnbull 2015-02-14 12:37 ` Eli Zaretskii 2015-02-14 15:32 ` Stephen Leake 1 sibling, 1 reply; 765+ messages in thread From: Stephen J. Turnbull @ 2015-02-14 12:18 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stephen Leake, emacs-devel Eli Zaretskii writes: > > From: Stephen Leake <stephen_leake@stephe-leake.org> > > Date: Fri, 13 Feb 2015 15:48:07 -0600 > > > > My use case requires calling lisp functions; in particular, > > put-text-property, but also other higher-level lisp functions in > > ada-mode. > > Why do you need to call Lisp in the module? I think it's a no-no for > modules to call Lisp; that should be done in the Lisp code that uses > the module. I don't understand. XEmacs's ELLs (dynamically loadable modules) have no problem with calling Lisp (use Ffuncall) or using symbols (use Fintern). The only requirement that I've seen expressed in this thread that XEmacs ELLs don't satisfy is that a module should be compilable for use with multiple versions of XEmacs (of course modules actually work with multiple versions, but that's not officially supported). XEmacs also doesn't really support unloading, although there's an unload function (there is no real guarantee that everything of interest will be cleaned), but I can't really see why that's an important requirement. It's mostly a convenience to enable a fast compile-load-test-unload cycle, and if it works half the time, it's a significant saving over compile-restart-load-test. > > I need a compiled module to implement an LALR parser for the Ada > > language that is fast enough for very large files. > > Why does an implementation of a parser need to call Lisp? I can't give you a reason in the case of a parser, but in general compiled Lisp functions may want to provide Lisp hooks, or implement inner loops for simple functionality in C but do flexible handling of more complex functionality in Lisp. Perhaps a similar motivation is relevant to the Ada parser. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 12:18 ` Stephen J. Turnbull @ 2015-02-14 12:37 ` Eli Zaretskii 2015-02-14 14:38 ` Stefan Monnier 2015-02-14 16:48 ` Stephen J. Turnbull 0 siblings, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-02-14 12:37 UTC (permalink / raw) To: Stephen J. Turnbull; +Cc: stephen_leake, emacs-devel > From: "Stephen J. Turnbull" <stephen@xemacs.org> > Cc: Stephen Leake <stephen_leake@stephe-leake.org>, > emacs-devel@gnu.org > Date: Sat, 14 Feb 2015 21:18:51 +0900 > > Eli Zaretskii writes: > > > From: Stephen Leake <stephen_leake@stephe-leake.org> > > > Date: Fri, 13 Feb 2015 15:48:07 -0600 > > > > > > My use case requires calling lisp functions; in particular, > > > put-text-property, but also other higher-level lisp functions in > > > ada-mode. > > > > Why do you need to call Lisp in the module? I think it's a no-no for > > modules to call Lisp; that should be done in the Lisp code that uses > > the module. > > I don't understand. XEmacs's ELLs (dynamically loadable modules) have > no problem with calling Lisp (use Ffuncall) or using symbols (use > Fintern). The only requirement that I've seen expressed in this > thread that XEmacs ELLs don't satisfy is that a module should be > compilable for use with multiple versions of XEmacs This last requirement is what is being discussed here. The capability of creating Lisp objects depends on the internals, and AFAIU we would like to avoid having that dependency. > > Why does an implementation of a parser need to call Lisp? > > I can't give you a reason in the case of a parser, but in general > compiled Lisp functions may want to provide Lisp hooks, or implement > inner loops for simple functionality in C but do flexible handling of > more complex functionality in Lisp. I wasn't talking about using Lisp by modules, I was talking specifically about calling Lisp from C. Implementing new primitives for performance purposes doesn't need that, at least it isn't clear to me why it would. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 12:37 ` Eli Zaretskii @ 2015-02-14 14:38 ` Stefan Monnier 2015-02-14 14:58 ` Eli Zaretskii 2015-02-14 16:48 ` Stephen J. Turnbull 1 sibling, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-02-14 14:38 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stephen J. Turnbull, stephen_leake, emacs-devel > The capability of creating Lisp objects depends on the internals, It doesn't have to be. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 14:38 ` Stefan Monnier @ 2015-02-14 14:58 ` Eli Zaretskii 2015-02-15 18:36 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-14 14:58 UTC (permalink / raw) To: Stefan Monnier; +Cc: stephen, stephen_leake, emacs-devel > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Cc: "Stephen J. Turnbull" <stephen@xemacs.org>, stephen_leake@stephe-leake.org, > emacs-devel@gnu.org > Date: Sat, 14 Feb 2015 09:38:38 -0500 > > > The capability of creating Lisp objects depends on the internals, > > It doesn't have to be. Not sure what you mean here; can you elaborate? What I had in mind was all the recent changes to internals of Lisp objects. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 14:58 ` Eli Zaretskii @ 2015-02-15 18:36 ` Stefan Monnier 2015-02-15 18:55 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-02-15 18:36 UTC (permalink / raw) To: Eli Zaretskii; +Cc: stephen, stephen_leake, emacs-devel >> > The capability of creating Lisp objects depends on the internals, >> It doesn't have to be. > Not sure what you mean here; can you elaborate? You don't need to know anything about the Lisp_Object representation (other than it's an EMACS_INT) to call Fcons, Fintern, Fcar, ... Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 18:36 ` Stefan Monnier @ 2015-02-15 18:55 ` Eli Zaretskii 2015-02-15 22:36 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-15 18:55 UTC (permalink / raw) To: Stefan Monnier; +Cc: stephen, stephen_leake, emacs-devel > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Cc: stephen@xemacs.org, stephen_leake@stephe-leake.org, emacs-devel@gnu.org > Date: Sun, 15 Feb 2015 13:36:20 -0500 > > >> > The capability of creating Lisp objects depends on the internals, > >> It doesn't have to be. > > Not sure what you mean here; can you elaborate? > > You don't need to know anything about the Lisp_Object representation > (other than it's an EMACS_INT) to call Fcons, Fintern, Fcar, ... Not every Lisp object has such a function. And what about the other direction: access a Lisp object's data from C? That is done almost entirely in C macros. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 18:55 ` Eli Zaretskii @ 2015-02-15 22:36 ` Stefan Monnier 0 siblings, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2015-02-15 22:36 UTC (permalink / raw) To: Eli Zaretskii; +Cc: stephen, stephen_leake, emacs-devel > Not every Lisp object has such a function. But we can provide such functions very easily. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 12:37 ` Eli Zaretskii 2015-02-14 14:38 ` Stefan Monnier @ 2015-02-14 16:48 ` Stephen J. Turnbull 2015-02-14 17:22 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Stephen J. Turnbull @ 2015-02-14 16:48 UTC (permalink / raw) To: Eli Zaretskii; +Cc: stephen_leake, emacs-devel Eli Zaretskii writes: > > I don't understand. XEmacs's ELLs (dynamically loadable modules) > > have no problem with calling Lisp (use Ffuncall) or using symbols > > (use Fintern). The only requirement that I've seen expressed in > > this thread that XEmacs ELLs don't satisfy is that a module > > should be compilable for use with multiple versions of XEmacs > > This last requirement is what is being discussed here. The capability > of creating Lisp objects depends on the internals, and AFAIU we would > like to avoid having that dependency. It's not very hard to get backward compatibility (old compiled modules work in new Emacs). Define a stable ABI, and then stick to it. It shouldn't be that hard to do it. Most Lisp functionality of most types is accessed through the object header, which points to a class descriptor, which is basically a table of methods. In XEmacs there's a constructor, a finalizer (optional), a printer, a gc-marker (optional), and a couple of others I forget offhand. Add a length indicator at the beginning, never change the order of methods from past versions, and I think you're done. If you add new methods in new Emacs, no problem, just add them at the end of the table. If you deprecate old ones, just leave the slots and insert an unimplemented marker (probably (slot_fun *) NULL will do but you could get fancy and have a slot_deprecated_fun to put in that slot). Sure, unneeded slots may accumulate over time, but you're going to have only a few dozen types at most and a couple unused slots per type. Then require that module functions access other modules (including core) only through Lisp (ie, Ffuncall and Fintern), which has a very stylized calling convention. If you find more efficiency is needed by some modules, you can expand the allowed functions in new Emacs. > I wasn't talking about using Lisp by modules, I was talking > specifically about calling Lisp from C. Implementing new > primitives for performance purposes doesn't need that, at least it > isn't clear to me why it would. I just don't see what the problem is. We call Lisp from C all the time, that's what Ffuncall *is*. It appears in most backtraces. :-) I don't know about Emacs conventions back when you had GCPROs, but in XEmacs you see functions marked "can GC" all over the place, precisely because they call Lisp. In the above, I'm being a little facetious, but it seems to me that calling Lisp from C is much safer and more straightforward than calling C from C. Up to GCPRO, but Emacs doesn't have that any more, correct? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 16:48 ` Stephen J. Turnbull @ 2015-02-14 17:22 ` Eli Zaretskii 2015-02-15 8:03 ` Stephen J. Turnbull 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-14 17:22 UTC (permalink / raw) To: Stephen J. Turnbull; +Cc: stephen_leake, emacs-devel > From: "Stephen J. Turnbull" <stephen@xemacs.org> > Cc: stephen_leake@stephe-leake.org, > emacs-devel@gnu.org > Date: Sun, 15 Feb 2015 01:48:50 +0900 > > Eli Zaretskii writes: > > > > I don't understand. XEmacs's ELLs (dynamically loadable modules) > > > have no problem with calling Lisp (use Ffuncall) or using symbols > > > (use Fintern). The only requirement that I've seen expressed in > > > this thread that XEmacs ELLs don't satisfy is that a module > > > should be compilable for use with multiple versions of XEmacs > > > > This last requirement is what is being discussed here. The capability > > of creating Lisp objects depends on the internals, and AFAIU we would > > like to avoid having that dependency. > > It's not very hard to get backward compatibility (old compiled modules > work in new Emacs). Define a stable ABI, and then stick to it. I simply don't believe this goal to be practically achievable, if there are no limitations on the interface. I also am not sure that people would accept forward incompatibility easily: consider the number of people who use bleeding-edge Org, Gnus, etc. with the last official release of Emacs. Why would they agree to lose that when part of a module is in C? > It shouldn't be that hard to do it. Most Lisp functionality of most > types is accessed through the object header, which points to a class > descriptor, which is basically a table of methods. In XEmacs there's > a constructor, a finalizer (optional), a printer, a gc-marker > (optional), and a couple of others I forget offhand. Add a length > indicator at the beginning, never change the order of methods from > past versions, and I think you're done. If you add new methods in new > Emacs, no problem, just add them at the end of the table. If you > deprecate old ones, just leave the slots and insert an unimplemented > marker (probably (slot_fun *) NULL will do but you could get fancy and > have a slot_deprecated_fun to put in that slot). Sure, unneeded slots > may accumulate over time, but you're going to have only a few dozen > types at most and a couple unused slots per type. Emacs objects aren't built that way, so part of what you say is inapplicable. But the real problems don't happen at that level, they are elsewhere, see below. > Then require that module functions access other modules (including > core) only through Lisp (ie, Ffuncall and Fintern), which has a very > stylized calling convention. And what about accessing Lisp objects? Most of them are accessed through C macros, whose definitions change as the internals change. What can you do with those to preserve compatibility across Emacs versions? > > I wasn't talking about using Lisp by modules, I was talking > > specifically about calling Lisp from C. Implementing new > > primitives for performance purposes doesn't need that, at least it > > isn't clear to me why it would. > > I just don't see what the problem is. We call Lisp from C all the > time, that's what Ffuncall *is*. It appears in most backtraces. :-) It appears in most backtraces because the Lisp interpreter calls it when it sees funcall in Lisp. More to the point: I simply don't see any reason for calling Lisp from C. If a module needs to do something in Lisp, let it do it in Lisp directly, as every external package for Emacs does. C code should be reserved for providing additional primitives that core Emacs lacks, and that's all. At least that should be the starting point, IMO. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 17:22 ` Eli Zaretskii @ 2015-02-15 8:03 ` Stephen J. Turnbull 2015-02-15 12:46 ` Steinar Bang 2015-02-15 17:33 ` Eli Zaretskii 0 siblings, 2 replies; 765+ messages in thread From: Stephen J. Turnbull @ 2015-02-15 8:03 UTC (permalink / raw) To: Eli Zaretskii; +Cc: stephen_leake, emacs-devel Eli Zaretskii writes: > > From: "Stephen J. Turnbull" <stephen@xemacs.org> > I simply don't believe this goal to be practically achievable, if > there are no limitations on the interface. The limitation is obvious: in principle, all Lisp objects are accessed through Lisp, with the exception of numbers. Even for strings and buffers you can call Lisp "coding system" functions. You may need to add an "internal char[] buffer" type to serve as source/sink (I'm sure you already have one for stream I/O, but it probably doesn't have a formal or stable definition). > I also am not sure that people would accept forward incompatibility > easily: consider the number of people who use bleeding-edge Org, Gnus, > etc. with the last official release of Emacs. Why would they agree to > lose that when part of a module is in C? For the same reasons they do when a package decides to use some new feature of Lisp that is forward incompatible. Mostly, they have no choice if the package decides to do that. Upgrade their Emacs or lose out. But I don't think you need to worry that the package maintainers will gratuitously break compatibility for users of C modules. If Emacs is unwilling to be disciplined, package maintainers won't use C modules, or will call through Lisp and otherwise treat external Lisp objects as opaque. > And what about accessing Lisp objects? Most of them are accessed > through C macros, whose definitions change as the internals change. > What can you do with those to preserve compatibility across Emacs > versions? Prohibit such change, or add accessor functions with a stable ABI encapsulating the accessor macros to a table for use by externally compiled modules loaded at runtime. A C function call is very cheap compared to a Lisp funcall. If this is too expensive the module probably shouldn't be based on Emacs at all, or it can be moved into core as has been done traditionally. It's that simple, both as a constraint on core development and as a software engineering technique. This is not rocket science, and hasn't been for a decade and a half now. It's just work, which the core developers can and should impose on the folks who want the feature. If you expect you must change some ABI in the future and can't/won't use the method table approach, tell module writers to access them *through* Lisp and live with funcall overhead. I assure you there are plenty of features that can benefit from C code that can live very happily even with that restriction. > More to the point: I simply don't see any reason for calling Lisp from > C. If a module needs to do something in Lisp, let it do it in Lisp > directly, as every external package for Emacs does. C code should > be reserved for providing additional primitives that core Emacs > lacks, and that's all. At least that should be the starting point, > IMO. But you're not the one who wants this feature. The people who do want this feature, in both XEmacs (which has more than a decade of experience with ELLs) and now in Emacs, have accessed, or think they need to access, Lisp objects from their C code. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 8:03 ` Stephen J. Turnbull @ 2015-02-15 12:46 ` Steinar Bang 2015-02-15 17:33 ` Eli Zaretskii 1 sibling, 0 replies; 765+ messages in thread From: Steinar Bang @ 2015-02-15 12:46 UTC (permalink / raw) To: emacs-devel >>>>> "Stephen J. Turnbull" <turnbull@sk.tsukuba.ac.jp>: > But you're not the one who wants this feature. The people who do want > this feature, in both XEmacs (which has more than a decade of > experience with ELLs) and now in Emacs, have accessed, or think they > need to access, Lisp objects from their C code. A good use case seems to be the Ada parser mentioned in this thread, where it is desirable to call lisp code from the parser semantic actions. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 8:03 ` Stephen J. Turnbull 2015-02-15 12:46 ` Steinar Bang @ 2015-02-15 17:33 ` Eli Zaretskii 2015-02-15 18:47 ` Stefan Monnier 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-15 17:33 UTC (permalink / raw) To: Stephen J. Turnbull; +Cc: stephen_leake, emacs-devel > From: "Stephen J. Turnbull" <turnbull@sk.tsukuba.ac.jp> > Cc: stephen_leake@stephe-leake.org, > emacs-devel@gnu.org > Date: Sun, 15 Feb 2015 17:03:21 +0900 > > > I simply don't believe this goal to be practically achievable, if > > there are no limitations on the interface. > > The limitation is obvious: in principle, all Lisp objects are accessed > through Lisp Not sure what that means in practice. What would be the definition of a Lisp_Object visible to a module? Will it be what we have on lisp.h, or some opaque object? > with the exception of numbers. Why the exception? What if the internal representation of a number changes? (It already did, a few weeks ago.) > Even for strings and buffers you can call Lisp "coding system" > functions. You may need to add an "internal char[] buffer" type to > serve as source/sink (I'm sure you already have one for stream I/O, > but it probably doesn't have a formal or stable definition). I don't follow: why coding-systems are relevant here? Perhaps you have XEmacs implementation in mind. > > I also am not sure that people would accept forward incompatibility > > easily: consider the number of people who use bleeding-edge Org, Gnus, > > etc. with the last official release of Emacs. Why would they agree to > > lose that when part of a module is in C? > > For the same reasons they do when a package decides to use some new > feature of Lisp that is forward incompatible. Using Lisp objects is not a new feature, so I don't think this analogy will hold water. > If Emacs is unwilling to be disciplined, package maintainers won't > use C modules, or will call through Lisp and otherwise treat > external Lisp objects as opaque. I think they will rather apply pressure to avoid changes that break binary compatibility, which in the long run will limit development. Not sure if we want that; something to discuss, I guess. > > And what about accessing Lisp objects? Most of them are accessed > > through C macros, whose definitions change as the internals change. > > What can you do with those to preserve compatibility across Emacs > > versions? > > Prohibit such change, or add accessor functions with a stable ABI > encapsulating the accessor macros to a table for use by externally > compiled modules loaded at runtime. That's what I tried to do in my suggestion for the API, but I don't hold my breath to see it accepted. Stephen Leake already said he didn't like it; I have no reason to believe I will hear anything different from others. The way the current modules on the branch are written are a good sign of what will follow, I think. > If you expect you must change some ABI in the future and can't/won't > use the method table approach, tell module writers to access them > *through* Lisp and live with funcall overhead. How can funcall help you access Lisp objects and convert their values to something that C can grok? Sooner or later, you will have to access the internals of the objects. So the funcall issue is irrelevant to accessing Lisp objects. > > More to the point: I simply don't see any reason for calling Lisp from > > C. If a module needs to do something in Lisp, let it do it in Lisp > > directly, as every external package for Emacs does. C code should > > be reserved for providing additional primitives that core Emacs > > lacks, and that's all. At least that should be the starting point, > > IMO. > > But you're not the one who wants this feature. The people who do want > this feature, in both XEmacs (which has more than a decade of > experience with ELLs) and now in Emacs, have accessed, or think they > need to access, Lisp objects from their C code. Yes, I understand that. And because of that I don't believe the "stable API" paradigm will be accepted. I think people will want to write modules with the same freedom and flexibility we write core code. Which means the "tightly-coupled" paradigm. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 17:33 ` Eli Zaretskii @ 2015-02-15 18:47 ` Stefan Monnier 2015-02-15 19:00 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-02-15 18:47 UTC (permalink / raw) To: Eli Zaretskii; +Cc: stephen_leake, Stephen J. Turnbull, emacs-devel > a Lisp_Object visible to a module? Will it be what we have on lisp.h, > or some opaque object? It'll be opaque (i.e. EMACS_INT and that's it, everything else happens via function calls). Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 18:47 ` Stefan Monnier @ 2015-02-15 19:00 ` Eli Zaretskii 2015-02-15 22:40 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-15 19:00 UTC (permalink / raw) To: Stefan Monnier; +Cc: stephen_leake, turnbull, emacs-devel > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Cc: "Stephen J. Turnbull" <turnbull@sk.tsukuba.ac.jp>, > stephen_leake@stephe-leake.org, emacs-devel@gnu.org > Date: Sun, 15 Feb 2015 13:47:56 -0500 > > > a Lisp_Object visible to a module? Will it be what we have on lisp.h, > > or some opaque object? > > It'll be opaque (i.e. EMACS_INT and that's it, everything else happens > via function calls). But even a definition of EMACS_INT comes with a lot of baggage, just look at lisp.h with fresh eyes. IOW, you should present a more complete proposal, if you want to convince (including convince yourself ;-) that this concept can hold enough water. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 19:00 ` Eli Zaretskii @ 2015-02-15 22:40 ` Stefan Monnier 0 siblings, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2015-02-15 22:40 UTC (permalink / raw) To: Eli Zaretskii; +Cc: stephen_leake, turnbull, emacs-devel > But even a definition of EMACS_INT comes with a lot of baggage, just > look at lisp.h with fresh eyes. M-x module-make RET would very easily be in a position to provide the right definition of EMACS_INT. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 8:39 ` Eli Zaretskii 2015-02-14 12:18 ` Stephen J. Turnbull @ 2015-02-14 15:32 ` Stephen Leake 2015-02-14 16:02 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Stephen Leake @ 2015-02-14 15:32 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Stephen Leake <stephen_leake@stephe-leake.org> >> Date: Fri, 13 Feb 2015 15:48:07 -0600 >> >> My use case requires calling lisp functions; in particular, >> put-text-property, but also other higher-level lisp functions in >> ada-mode. > > Why do you need to call Lisp in the module? I think it's a no-no for > modules to call Lisp; that should be done in the Lisp code that uses > the module. > >> I need a compiled module to implement an LALR parser for the Ada >> language that is fast enough for very large files. > > Why does an implementation of a parser need to call Lisp? Emacs ada-mode does indentation in two steps; first it parses the source code, and the parser actions are lisp functions that eventually call put-text-property to store information about the syntax and/or semantics on many identifiers. Then the indentation code uses those text properties to compute indentation. I have a generalized LALR parser implemented in elisp that is fast enough for many user's Ada files, but some users have much bigger files, and it takes them 10 seconds to parse. So I need a faster implementation. So far my benchmarking says I can get close with a machine compiled parser. So the module would contain the generalized LALR parser; the actions of the parser would still be calls to the lisp functions. Of course, lisp put-text-property is implemented in C, so I could reimplement the parser actions in the module, and call that C function directly. But it would be convenient to be able to call the higher-level lisp parser action functions from the module; that would simplify maintaining the module and elisp parser implementations in parallel. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 15:32 ` Stephen Leake @ 2015-02-14 16:02 ` Eli Zaretskii 2015-02-14 16:45 ` Eli Zaretskii 2015-02-15 0:35 ` Stephen Leake 0 siblings, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-02-14 16:02 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel > From: Stephen Leake <stephen_leake@stephe-leake.org> > Date: Sat, 14 Feb 2015 09:32:54 -0600 > > Emacs ada-mode does indentation in two steps; first it parses the source > code, and the parser actions are lisp functions that eventually call > put-text-property to store information about the syntax and/or semantics > on many identifiers. Then the indentation code uses those text > properties to compute indentation. > > I have a generalized LALR parser implemented in elisp that is fast > enough for many user's Ada files, but some users have much bigger files, > and it takes them 10 seconds to parse. So I need a faster > implementation. So far my benchmarking says I can get close with a > machine compiled parser. > > So the module would contain the generalized LALR parser; the actions of > the parser would still be calls to the lisp functions. But this means your mode is in Lisp to begin with, and it just calls functions implemented in C to work faster. So you could leave the calls to put-text-property in Lisp, and have the functions implemented in the module return the information required to compute the arguments to put-text-property. Or am I missing something? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 16:02 ` Eli Zaretskii @ 2015-02-14 16:45 ` Eli Zaretskii 2015-02-15 0:39 ` Stephen Leake 2015-02-15 0:35 ` Stephen Leake 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-14 16:45 UTC (permalink / raw) To: stephen_leake; +Cc: emacs-devel > Date: Sat, 14 Feb 2015 18:02:22 +0200 > From: Eli Zaretskii <eliz@gnu.org> > Cc: emacs-devel@gnu.org > > > From: Stephen Leake <stephen_leake@stephe-leake.org> > > Date: Sat, 14 Feb 2015 09:32:54 -0600 > > > > Emacs ada-mode does indentation in two steps; first it parses the source > > code, and the parser actions are lisp functions that eventually call > > put-text-property to store information about the syntax and/or semantics > > on many identifiers. Then the indentation code uses those text > > properties to compute indentation. > > > > I have a generalized LALR parser implemented in elisp that is fast > > enough for many user's Ada files, but some users have much bigger files, > > and it takes them 10 seconds to parse. So I need a faster > > implementation. So far my benchmarking says I can get close with a > > machine compiled parser. > > > > So the module would contain the generalized LALR parser; the actions of > > the parser would still be calls to the lisp functions. > > But this means your mode is in Lisp to begin with, and it just calls > functions implemented in C to work faster. So you could leave the > calls to put-text-property in Lisp, and have the functions implemented > in the module return the information required to compute the arguments > to put-text-property. Or am I missing something? And btw, what exactly do you mean by "call Lisp" in this case? Call put-text-property, which is implemented in C in its entirety, doesn't constitute a call to Lisp in my book. Of course, that means we will want to export Fput_text_property... ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 16:45 ` Eli Zaretskii @ 2015-02-15 0:39 ` Stephen Leake 2015-02-15 13:54 ` Daniel Colascione 2015-02-15 18:43 ` Stefan Monnier 0 siblings, 2 replies; 765+ messages in thread From: Stephen Leake @ 2015-02-15 0:39 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> Date: Sat, 14 Feb 2015 18:02:22 +0200 >> From: Eli Zaretskii <eliz@gnu.org> >> Cc: emacs-devel@gnu.org >> >> > From: Stephen Leake <stephen_leake@stephe-leake.org> >> > Date: Sat, 14 Feb 2015 09:32:54 -0600 >> > >> > Emacs ada-mode does indentation in two steps; first it parses the source >> > code, and the parser actions are lisp functions that eventually call >> > put-text-property to store information about the syntax and/or semantics >> > on many identifiers. Then the indentation code uses those text >> > properties to compute indentation. >> > >> > I have a generalized LALR parser implemented in elisp that is fast >> > enough for many user's Ada files, but some users have much bigger files, >> > and it takes them 10 seconds to parse. So I need a faster >> > implementation. So far my benchmarking says I can get close with a >> > machine compiled parser. >> > >> > So the module would contain the generalized LALR parser; the actions of >> > the parser would still be calls to the lisp functions. >> >> But this means your mode is in Lisp to begin with, and it just calls >> functions implemented in C to work faster. So you could leave the >> calls to put-text-property in Lisp, and have the functions implemented >> in the module return the information required to compute the arguments >> to put-text-property. Or am I missing something? > > And btw, what exactly do you mean by "call Lisp" in this case? Call > put-text-property, which is implemented in C in its entirety, doesn't > constitute a call to Lisp in my book. The parser actions are higher level lisp functions; they do call put-text-property, but there is significant logic in the lisp, and I'd rather not re-implement that in the module, to simplify maintenance. I'll have to maintain both the elisp and module implementations, for two reasons: - emacs 24 doesn't support modules - some (many?) ada-mode users won't bother to compile the module (and I don't plan to distribute a binary). > Of course, that means we will want to export Fput_text_property... Right, that might be needed at some point. Right now I'll settle for 'funcall'. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 0:39 ` Stephen Leake @ 2015-02-15 13:54 ` Daniel Colascione 2015-02-15 18:08 ` Stephen Leake 2015-02-15 18:43 ` Stefan Monnier 1 sibling, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-02-15 13:54 UTC (permalink / raw) To: Stephen Leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1719 bytes --] On 02/14/2015 04:39 PM, Stephen Leake wrote: > Eli Zaretskii <eliz@gnu.org> writes: > >>> Date: Sat, 14 Feb 2015 18:02:22 +0200 >>> From: Eli Zaretskii <eliz@gnu.org> >>> Cc: emacs-devel@gnu.org >>> >>>> From: Stephen Leake <stephen_leake@stephe-leake.org> >>>> Date: Sat, 14 Feb 2015 09:32:54 -0600 >>>> >>>> Emacs ada-mode does indentation in two steps; first it parses the source >>>> code, and the parser actions are lisp functions that eventually call >>>> put-text-property to store information about the syntax and/or semantics >>>> on many identifiers. Then the indentation code uses those text >>>> properties to compute indentation. >>>> >>>> I have a generalized LALR parser implemented in elisp that is fast >>>> enough for many user's Ada files, but some users have much bigger files, >>>> and it takes them 10 seconds to parse. So I need a faster >>>> implementation. So far my benchmarking says I can get close with a >>>> machine compiled parser. You don't a parser in C. You need a smarter parser. Look up "incremental", please. >>>> >>>> So the module would contain the generalized LALR parser; the actions of >>>> the parser would still be calls to the lisp functions. The right way to let C libraries call Lisp functions is to let C libraries accept C callback functions, then thunk from C callbacks to Lisp functions in the CFFI layer. That's what other CFFI implementations do. This way, your library _still_ doesn't need to know about specific Lisp internals. The module proposal in this thread will harm Emacs development because it'll put unnecessary constraints on the elisp implementations. Look at how much trouble PyPy has with CPython modules. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 13:54 ` Daniel Colascione @ 2015-02-15 18:08 ` Stephen Leake 0 siblings, 0 replies; 765+ messages in thread From: Stephen Leake @ 2015-02-15 18:08 UTC (permalink / raw) To: emacs-devel Daniel Colascione <dancol@dancol.org> writes: > On 02/14/2015 04:39 PM, Stephen Leake wrote: >> Eli Zaretskii <eliz@gnu.org> writes: >> >>>> Date: Sat, 14 Feb 2015 18:02:22 +0200 >>>> From: Eli Zaretskii <eliz@gnu.org> >>>> Cc: emacs-devel@gnu.org >>>> >>>>> From: Stephen Leake <stephen_leake@stephe-leake.org> >>>>> Date: Sat, 14 Feb 2015 09:32:54 -0600 >>>>> >>>>> Emacs ada-mode does indentation in two steps; first it parses the source >>>>> code, and the parser actions are lisp functions that eventually call >>>>> put-text-property to store information about the syntax and/or semantics >>>>> on many identifiers. Then the indentation code uses those text >>>>> properties to compute indentation. >>>>> >>>>> I have a generalized LALR parser implemented in elisp that is fast >>>>> enough for many user's Ada files, but some users have much bigger files, >>>>> and it takes them 10 seconds to parse. So I need a faster >>>>> implementation. So far my benchmarking says I can get close with a >>>>> machine compiled parser. > > You don't a parser in C. You need a smarter parser. Look up > "incremental", please. Yes, an incremental parser would help. I have looked at that; I'd much rather write that in Ada than in lisp. I tried using an Ada parser in a separate process communication via pipes over stdin/stdout; the communications overhead was too much. So a module implementation would still be a good thing. For the moment, just moving the current parser into a module is the first step; if that is not fast enough, implementing an incremental parser is the next step. >>>>> So the module would contain the generalized LALR parser; the actions of >>>>> the parser would still be calls to the lisp functions. > > The right way to let C libraries call Lisp functions is to let C > libraries accept C callback functions, then thunk from C callbacks to > Lisp functions in the CFFI layer. That's what other CFFI implementations > do. This way, your library _still_ doesn't need to know about specific > Lisp internals. > > The module proposal in this thread will harm Emacs development because > it'll put unnecessary constraints on the elisp implementations. Look at > how much trouble PyPy has with CPython modules. It appears that the people actually working on this issue don't have experience with the various forms of module interface. Perhaps you could take a stab at writing a CFFI layer that is sufficient for the curl module? -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 0:39 ` Stephen Leake 2015-02-15 13:54 ` Daniel Colascione @ 2015-02-15 18:43 ` Stefan Monnier 2015-02-15 18:56 ` Eli Zaretskii 2015-02-15 19:27 ` joakim 1 sibling, 2 replies; 765+ messages in thread From: Stefan Monnier @ 2015-02-15 18:43 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel > The parser actions are higher level lisp functions; they do call > put-text-property, but there is significant logic in the lisp, and I'd > rather not re-implement that in the module, to simplify maintenance. I don't see why calling Elisp from a C (or Ada) module would cause any kind of problem, so this approach looks fine to me. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 18:43 ` Stefan Monnier @ 2015-02-15 18:56 ` Eli Zaretskii 2015-02-16 4:52 ` Stephen J. Turnbull 2015-02-15 19:27 ` joakim 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-15 18:56 UTC (permalink / raw) To: Stefan Monnier; +Cc: stephen_leake, emacs-devel > From: Stefan Monnier <monnier@IRO.UMontreal.CA> > Date: Sun, 15 Feb 2015 13:43:45 -0500 > Cc: emacs-devel@gnu.org > > > The parser actions are higher level lisp functions; they do call > > put-text-property, but there is significant logic in the lisp, and I'd > > rather not re-implement that in the module, to simplify maintenance. > > I don't see why calling Elisp from a C (or Ada) module would cause any > kind of problem, so this approach looks fine to me. Look at the modules on the branch to see where this is going. It certainly contradicts your "no need to know about internals of Lisp objects" concept. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 18:56 ` Eli Zaretskii @ 2015-02-16 4:52 ` Stephen J. Turnbull 2015-02-16 13:44 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Stephen J. Turnbull @ 2015-02-16 4:52 UTC (permalink / raw) To: Eli Zaretskii; +Cc: stephen_leake, Stefan Monnier, emacs-devel Eli Zaretskii writes: > Look at the modules on the branch to see where this is going. It > certainly contradicts your "no need to know about internals of Lisp > objects" concept. No, it simply means that the current modules are programmed by people who know about dlopen and Emacs internals and have not thought about designing a runtime environment for the modules. Daniel's proposal makes a lot of sense, and is better than the current S?XEmacs design. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-16 4:52 ` Stephen J. Turnbull @ 2015-02-16 13:44 ` Aurélien Aptel 0 siblings, 0 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-02-16 13:44 UTC (permalink / raw) To: Stephen J. Turnbull Cc: Eli Zaretskii, Stephen Leake, Stefan Monnier, Emacs development discussions I've let this sit for a few days, didn't expect so much feedback, good! I was in favor of a tight integration (like Linux kernel modules which are in the same repository as the kernel) about after reading everything I'm not sure what to think anymore. Keeping modules uptodate with Emacs while also backporting features to older Emacs is insane, that's for sure. In any case rewriting current modules is not a problem, they are very simple and meant as examples/POCs. On Mon, Feb 16, 2015 at 5:52 AM, Stephen J. Turnbull <stephen@xemacs.org> wrote: > No, it simply means that the current modules are programmed by people > who know about dlopen and Emacs internals and have not thought about > designing a runtime environment for the modules. I'm far from an expert, yes. I'm just the guy who wanted to extend Emacs in C without recompiling it and acted on it. A real FFI would be better than a module API but I'm not sure how to handle certain things: making/passing struct pointers and callbacks, mainly. I don't know if it can be efficient either. > Daniel's proposal makes a lot of sense, and is better than the current > S?XEmacs design. Daniel's proposal is very good yes, it's the most convincing solution I think. And as he said the FFI can be implemented on top of it. I just hope all the type conversion and intern() calls won't ruin performances. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 18:43 ` Stefan Monnier 2015-02-15 18:56 ` Eli Zaretskii @ 2015-02-15 19:27 ` joakim 2015-02-15 22:39 ` Stefan Monnier 1 sibling, 1 reply; 765+ messages in thread From: joakim @ 2015-02-15 19:27 UTC (permalink / raw) To: Stefan Monnier; +Cc: Stephen Leake, emacs-devel Stefan Monnier <monnier@IRO.UMontreal.CA> writes: >> The parser actions are higher level lisp functions; they do call >> put-text-property, but there is significant logic in the lisp, and I'd >> rather not re-implement that in the module, to simplify maintenance. > > I don't see why calling Elisp from a C (or Ada) module would cause any > kind of problem, so this approach looks fine to me. This is just my experience from implementing Xwidgets FWIW. Originally I tried having external code calling Emacs internals, but that was very unreliable. Then I switched to generating events that was handled by the Emacs eventloop, and that now works fine. The other way around, Emacs calling code in a module via the Gnome Introspection API works fine, except marshalling all the types isnt trivial. It would be nice if we could find some synergies between gnome object introspection and other FFI types. > > > Stefan > -- Joakim Verona ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 19:27 ` joakim @ 2015-02-15 22:39 ` Stefan Monnier 2015-02-16 13:53 ` joakim 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-02-15 22:39 UTC (permalink / raw) To: joakim; +Cc: Stephen Leake, emacs-devel > This is just my experience from implementing Xwidgets FWIW. > Originally I tried having external code calling Emacs internals, but > that was very unreliable. That's not because it was called from external code. It's because it was called asynchronously. What I meant by the above is that it's perfectly OK for module code to call back Elisp in cases such as when Fmapcar calls Elisp: synchronous calls. There are indeed various restrictions about *when* you can run Elisp. These apply to module code, but they also apply to core code. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 22:39 ` Stefan Monnier @ 2015-02-16 13:53 ` joakim 0 siblings, 0 replies; 765+ messages in thread From: joakim @ 2015-02-16 13:53 UTC (permalink / raw) To: Stefan Monnier; +Cc: Stephen Leake, emacs-devel Stefan Monnier <monnier@IRO.UMontreal.CA> writes: >> This is just my experience from implementing Xwidgets FWIW. >> Originally I tried having external code calling Emacs internals, but >> that was very unreliable. > > That's not because it was called from external code. It's because it > was called asynchronously. Yes, I should have clarified that. > > What I meant by the above is that it's perfectly OK for module code to > call back Elisp in cases such as when Fmapcar calls Elisp: > synchronous calls. > > There are indeed various restrictions about *when* you can run Elisp. > These apply to module code, but they also apply to core code. > > > Stefan > -- Joakim Verona ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 16:02 ` Eli Zaretskii 2015-02-14 16:45 ` Eli Zaretskii @ 2015-02-15 0:35 ` Stephen Leake 1 sibling, 0 replies; 765+ messages in thread From: Stephen Leake @ 2015-02-15 0:35 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Stephen Leake <stephen_leake@stephe-leake.org> >> Date: Sat, 14 Feb 2015 09:32:54 -0600 >> >> Emacs ada-mode does indentation in two steps; first it parses the source >> code, and the parser actions are lisp functions that eventually call >> put-text-property to store information about the syntax and/or semantics >> on many identifiers. Then the indentation code uses those text >> properties to compute indentation. >> >> I have a generalized LALR parser implemented in elisp that is fast >> enough for many user's Ada files, but some users have much bigger files, >> and it takes them 10 seconds to parse. So I need a faster >> implementation. So far my benchmarking says I can get close with a >> machine compiled parser. >> >> So the module would contain the generalized LALR parser; the actions of >> the parser would still be calls to the lisp functions. > > But this means your mode is in Lisp to begin with, and it just calls > functions implemented in C to work faster. So you could leave the > calls to put-text-property in Lisp, and have the functions implemented > in the module return the information required to compute the arguments > to put-text-property. Or am I missing something? The parser actions are callbacks; when the parser recognizes a complete grammar sentence (ie a statement, function declaration, etc), it calls an action (which in this case is a lisp function), then resumes parsing. Each file contains many grammar sentences, so there are many calls to lisp functions from within the C parser. (Actually, the parser is in Ada, but that's a separate issue). I could redefine the parser actions to store the required info in a list, and at the end of parsing return that list, and then process the list in elisp. But I've already tried that with the parser in an external process; just processing the returned list is too slow. I need direct calls. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 8:37 ` Eli Zaretskii 2015-02-13 12:17 ` Daniel Colascione @ 2015-02-13 19:11 ` Stefan Monnier 2015-02-14 19:12 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-02-13 19:11 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Paul Eggert, emacs-devel > I would start by coming up with the minimum set of requirements a > module needs to be able to communicate with Emacs. Easy: take the existing sample modules and see what they need. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 19:11 ` Stefan Monnier @ 2015-02-14 19:12 ` Eli Zaretskii 2015-02-14 19:25 ` Eli Zaretskii ` (2 more replies) 0 siblings, 3 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-02-14 19:12 UTC (permalink / raw) To: Stefan Monnier; +Cc: eggert, emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Date: Fri, 13 Feb 2015 14:11:33 -0500 > Cc: Paul Eggert <eggert@cs.ucla.edu>, emacs-devel@gnu.org > > > I would start by coming up with the minimum set of requirements a > > module needs to be able to communicate with Emacs. > > Easy: take the existing sample modules and see what they need. No one seems to care, so I will bite the bullet. The below is based on looking at the modules branch. It looks like modules need: . A function to replace the DEFUN macro and the related defsubr call. . Some definition of Lisp_Object This already presents at least 2 problems. The first is 32- vs 64-bit issues. We need some way of checking that a 32-bit module isn't loaded by a 64-bit Emacs, and vice versa. The other problem is more serious: Emacs can be built with or without --check-lisp-object-type, and with or without --wide-int; how will the module know which implementation to use? Perhaps the solution is to make Lisp_Object an opaque data type for the modules, and not use the definition we have on lisp.h. . Functions to access values of Lisp objects. We shouldn't rely on C macros like XINT and XWINDOW for that, because macros track too closely the internals of each object. So I propose to use functions that will be exposed via the API. . Functions to create Lisp objects and/or set their values. Again, we shouldn't rely on the likes of XSETCONS. There should be a function make_FOO for each object type FOO. This includes creating symbols, so 'intern' should not be needed by modules. . A function to create a Lisp object that is a container for a C struct or pointer. The above means that most of the C source files under modules/ should be thoroughly rewritten. They are currently written as if the code were an integral part of Emacs on one of the Emacs C files. Going that way means that modules will have to be recompiled from sources for each Emacs version, and practically will have to live in the Emacs tree. Maybe this is what we want, I don't know. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 19:12 ` Eli Zaretskii @ 2015-02-14 19:25 ` Eli Zaretskii 2015-02-15 1:02 ` Stephen Leake 2015-02-15 9:21 ` Stephen J. Turnbull 2 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-02-14 19:25 UTC (permalink / raw) To: monnier; +Cc: eggert, emacs-devel > Date: Sat, 14 Feb 2015 21:12:02 +0200 > From: Eli Zaretskii <eliz@gnu.org> > Cc: eggert@cs.ucla.edu, emacs-devel@gnu.org > > The above means that most of the C source files under modules/ should > be thoroughly rewritten. They are currently written as if the code > were an integral part of Emacs on one of the Emacs C files. Btw, one thing that the current code in modules/ entirely ignores is encoding of file names, URLs, and buffer/string text: the current code simply hands C pointers to string/buffer internals to C APIs. Modules should encode/decode them when they communicate with C library APIs, otherwise the result will be subtle bugs with non-ASCII text. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 19:12 ` Eli Zaretskii 2015-02-14 19:25 ` Eli Zaretskii @ 2015-02-15 1:02 ` Stephen Leake 2015-02-15 17:32 ` Eli Zaretskii 2015-02-15 19:30 ` Stefan Monnier 2015-02-15 9:21 ` Stephen J. Turnbull 2 siblings, 2 replies; 765+ messages in thread From: Stephen Leake @ 2015-02-15 1:02 UTC (permalink / raw) To: emacs-devel [-- Attachment #1: Type: text/plain, Size: 3439 bytes --] Eli Zaretskii <eliz@gnu.org> writes: >> From: Stefan Monnier <monnier@iro.umontreal.ca> >> Date: Fri, 13 Feb 2015 14:11:33 -0500 >> Cc: Paul Eggert <eggert@cs.ucla.edu>, emacs-devel@gnu.org >> >> > I would start by coming up with the minimum set of requirements a >> > module needs to be able to communicate with Emacs. >> >> Easy: take the existing sample modules and see what they need. > > No one seems to care, so I will bite the bullet. I took a stab at creating emacs_module_api.h; attached. To do this, I replaced "#include <lisp.h>" in modules/curl/curl.c with "#include <emacs_modules_api.h>", and copied stuff from lisp.h and other headers to emacs_module_api.h until it compiled. Note the FIXMEs; I could not figure out what was going on in some places, so I just kludged it for now. I don't know if this is useful, but it is my interpretation of what Stefan proposed; lisp.h would "#include emacs_modules_api.h". (He called it "emacs.h", but I think including 'modules' in the name is better). > The below is based > on looking at the modules branch. > > It looks like modules need: > > . A function to replace the DEFUN macro and the related defsubr call. > > . Some definition of Lisp_Object > > This already presents at least 2 problems. The first is 32- vs > 64-bit issues. We need some way of checking that a 32-bit module > isn't loaded by a 64-bit Emacs, and vice versa. Good point. That's a special case of "don't load a module compiled for processor X in an Emacs compiled for processor Y". gnu binutils has facilities for that. > The other problem is more serious: Emacs can be built with or > without --check-lisp-object-type, and with or without --wide-int; > how will the module know which implementation to use? Similar check when the module is loaded. Which means we need some metainfo for each module, and a standard function to retrieve it. > . Functions to access values of Lisp objects. We shouldn't rely on C > macros like XINT and XWINDOW for that, because macros track too > closely the internals of each object. So I propose to use > functions that will be exposed via the API. If we follow Stefan's suggestion, then either this function approach is not viable, or we need another #ifdef for module vs emacs. > The above means that most of the C source files under modules/ should > be thoroughly rewritten. Yes. > They are currently written as if the code were an integral part of > Emacs on one of the Emacs C files. Going that way means that modules > will have to be recompiled from sources for each Emacs version, and > practically will have to live in the Emacs tree. Maybe this is what we > want, I don't know. This is the model I had in mind. Since I need max speed with mixed Ada/lisp code, I need tight integration with the core. The people who need that speed for Ada mode will simply have to recompile the module for each Emacs release; they are coders, so that's not a problem. On the other hand, modules for other use cases (I have in mind a spam filter for Gnus) would not need to be nearly so tightly bound, so a more limited/safe API would be appropriate. Rather than splitting out emacs_module_api.h from lisp.h, we could add __declspec(dllexport) to a subset of the functions in lisp.h; I suspect that will be a small number. I'll give that a try next. Is there an equivalent on Linux (I don't recall ever seeing one)? -- -- Stephe [-- Attachment #2: emacs_modules_api.h --] [-- Type: application/octet-stream, Size: 37490 bytes --] /* Emacs modules API */ /* FIXME: for Windows, add __declspec(dllexport) to all (some?) of these */ /* #ifdef WINDOWS */ /* # ifdef emacs */ /* # define EMACS_EXPORT __declspec(dllexport) */ /* # else */ /* # define EMACS_EXPORT __declspec(dllimport) */ /* # endif */ /* # else */ /* # define EMACS_EXPORT */ /* #endif */ /* FIXME: <stdint.h> vs ../nt/inc/stdint.h:37 */ #include <stdint.h> /* conf_post.h:35 */ #include <stdbool.h> /* The type of bool bitfields. Needed to compile Objective-C with standard GCC. It was also needed to port to pre-C99 compilers, although we don't care about that any more. */ /* conf_post.h:40 */ #if NS_IMPL_GNUSTEP typedef unsigned int bool_bf; #else typedef bool bool_bf; #endif /* When not using Clang, assume its attributes and features are absent. */ /* conf_post.h:62 */ #ifndef __has_attribute # define __has_attribute(a) false #endif #ifndef __has_feature # define __has_feature(a) false #endif /* conf_post.h:226 */ #if (__clang__ \ ? __has_attribute (externally_visible) \ : (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))) #define EXTERNALLY_VISIBLE __attribute__((externally_visible)) #else #define EXTERNALLY_VISIBLE #endif /* FIXME: need to define INLINE */ /* conf_post.h:318 */ #define INLINE /* empty */ /* Define a TYPE constant ID as an externally visible name. Use like this: DEFINE_GDB_SYMBOL_BEGIN (TYPE, ID) # define ID (some integer preprocessor expression of type TYPE) DEFINE_GDB_SYMBOL_END (ID) This hack is for the benefit of compilers that do not make macro definitions or enums visible to the debugger. It's used for symbols that .gdbinit needs. */ /* lisp.h:11 */ #define DECLARE_GDB_SYM(type, id) type const id EXTERNALLY_VISIBLE #ifdef MAIN_PROGRAM # define DEFINE_GDB_SYMBOL_BEGIN(type, id) DECLARE_GDB_SYM (type, id) # define DEFINE_GDB_SYMBOL_END(id) = id; #else # define DEFINE_GDB_SYMBOL_BEGIN(type, id) extern DECLARE_GDB_SYM (type, id) # define DEFINE_GDB_SYMBOL_END(val) ; #endif /* Number of bits in a Lisp_Object tag. */ /* lisp.h:70 */ DEFINE_GDB_SYMBOL_BEGIN (int, GCTYPEBITS) #define GCTYPEBITS 3 DEFINE_GDB_SYMBOL_END (GCTYPEBITS) /* EMACS_INT - signed integer wide enough to hold an Emacs value EMACS_INT_MAX - maximum value of EMACS_INT; can be used in #if pI - printf length modifier for EMACS_INT EMACS_UINT - unsigned variant of EMACS_INT */ /* lisp.h:87 */ #ifndef EMACS_INT_MAX # if INTPTR_MAX <= 0 # error "INTPTR_MAX misconfigured" # elif INTPTR_MAX <= INT_MAX >> NONPOINTER_BITS && !defined WIDE_EMACS_INT typedef int EMACS_INT; typedef unsigned int EMACS_UINT; # define EMACS_INT_MAX INT_MAX # define pI "" # elif INTPTR_MAX <= LONG_MAX >> NONPOINTER_BITS && !defined WIDE_EMACS_INT typedef long int EMACS_INT; typedef unsigned long EMACS_UINT; # define EMACS_INT_MAX LONG_MAX # define pI "l" /* Check versus LLONG_MAX, not LLONG_MAX >> NONPOINTER_BITS. In theory this is not safe, but in practice it seems to be OK. */ # elif INTPTR_MAX <= LLONG_MAX typedef long long int EMACS_INT; typedef unsigned long long int EMACS_UINT; # define EMACS_INT_MAX LLONG_MAX # define pI "ll" # else # error "INTPTR_MAX too large" # endif #endif /* Number of bits in some machine integer types. */ /* lisp.h:134 */ enum { BITS_PER_CHAR = CHAR_BIT, BITS_PER_SHORT = CHAR_BIT * sizeof (short), BITS_PER_LONG = CHAR_BIT * sizeof (long int), BITS_PER_EMACS_INT = CHAR_BIT * sizeof (EMACS_INT) }; /* Define Emacs versions of <assert.h>'s 'assert (COND)' and <verify.h>'s 'assume (COND)'. COND should be free of side effects, as it may or may not be evaluated. 'eassert (COND)' checks COND at runtime if ENABLE_CHECKING is defined and suppress_checking is false, and does nothing otherwise. Emacs dies if COND is checked and is false. The suppress_checking variable is initialized to 0 in alloc.c. Set it to 1 using a debugger to temporarily disable aborting on detected internal inconsistencies or error conditions. In some cases, a good compiler may be able to optimize away the eassert macro even if ENABLE_CHECKING is true, e.g., if XSTRING (x) uses eassert to test STRINGP (x), but a particular use of XSTRING is invoked only after testing that STRINGP (x) is true, making the test redundant. eassume is like eassert except that it also causes the compiler to assume that COND is true afterwards, regardless of whether runtime checking is enabled. This can improve performance in some cases, though it can degrade performance in others. It's often suboptimal for COND to call external functions or access volatile storage. */ /* lisp.h:199 */ #ifndef ENABLE_CHECKING # define eassert(cond) ((void) (false && (cond))) /* Check COND compiles. */ # define eassume(cond) assume (cond) #else /* ENABLE_CHECKING */ extern _Noreturn void die (const char *, const char *, int); extern bool suppress_checking EXTERNALLY_VISIBLE; # define eassert(cond) \ (suppress_checking || (cond) \ ? (void) 0 \ : die (# cond, __FILE__, __LINE__)) # define eassume(cond) \ (suppress_checking \ ? assume (cond) \ : (cond) \ ? (void) 0 \ : die (# cond, __FILE__, __LINE__)) #endif /* ENABLE_CHECKING */ /* lisp.h:239 */ enum Lisp_Bits { /* 2**GCTYPEBITS. This must be a macro that expands to a literal integer constant, for MSVC. */ #define GCALIGNMENT 8 /* Number of bits in a Lisp_Object value, not counting the tag. */ VALBITS = BITS_PER_EMACS_INT - GCTYPEBITS, /* Number of bits in a Lisp fixnum tag. */ INTTYPEBITS = GCTYPEBITS - 1, /* Number of bits in a Lisp fixnum value, not counting the tag. */ FIXNUM_BITS = VALBITS + 1 }; /* The maximum value that can be stored in a EMACS_INT, assuming all bits other than the type bits contribute to a nonnegative signed value. This can be used in #if, e.g., '#if USB_TAG' below expands to an expression involving VAL_MAX. */ /* lisp.h:263 */ #define VAL_MAX (EMACS_INT_MAX >> (GCTYPEBITS - 1)) /* Whether the least-significant bits of an EMACS_INT contain the tag. On hosts where pointers-as-ints do not exceed VAL_MAX / 2, USE_LSB_TAG is: a. unnecessary, because the top bits of an EMACS_INT are unused, and b. slower, because it typically requires extra masking. So, USE_LSB_TAG is true only on hosts where it might be useful. */ /* lisp.h:270 */ /* FIXME: not working; just set it */ DEFINE_GDB_SYMBOL_BEGIN (bool, USE_LSB_TAG) #define USE_LSB_TAG 0 /* (VAL_MAX / 2 < INTPTR_MAX) */ DEFINE_GDB_SYMBOL_END (USE_LSB_TAG) /* FIXME: */ /* #if !USE_LSB_TAG && !defined WIDE_EMACS_INT */ /* # error "USE_LSB_TAG not supported on this platform; please report this." \ */ /* "Try 'configure --with-wide-int' to work around the problem." */ /* error !; */ /* #endif */ /* lisp.h:280 */ #ifndef alignas # define alignas(alignment) /* empty */ # if USE_LSB_TAG # error "USE_LSB_TAG requires alignas" # endif #endif /* lisp.h:287 */ #ifdef HAVE_STRUCT_ATTRIBUTE_ALIGNED # define GCALIGNED __attribute__ ((aligned (GCALIGNMENT))) #else # define GCALIGNED /* empty */ #endif /* Some operations are so commonly executed that they are implemented as macros, not functions, because otherwise runtime performance would suffer too much when compiling with GCC without optimization. There's no need to inline everything, just the operations that would otherwise cause a serious performance problem. For each such operation OP, define a macro lisp_h_OP that contains the operation's implementation. That way, OP can be implemented via a macro definition like this: #define OP(x) lisp_h_OP (x) and/or via a function definition like this: LISP_MACRO_DEFUN (OP, Lisp_Object, (Lisp_Object x), (x)) which macro-expands to this: Lisp_Object (OP) (Lisp_Object x) { return lisp_h_OP (x); } without worrying about the implementations diverging, since lisp_h_OP defines the actual implementation. The lisp_h_OP macros are intended to be private to this include file, and should not be used elsewhere. FIXME: Remove the lisp_h_OP macros, and define just the inline OP functions, once most developers have access to GCC 4.8 or later and can use "gcc -Og" to debug. Maybe in the year 2016. See Bug#11935. Commentary for these macros can be found near their corresponding functions, below. */ #if CHECK_LISP_OBJECT_TYPE # define lisp_h_XLI(o) ((o).i) # define lisp_h_XIL(i) ((Lisp_Object) { i }) #else # define lisp_h_XLI(o) (o) # define lisp_h_XIL(i) (i) #endif #define lisp_h_CHECK_LIST_CONS(x, y) CHECK_TYPE (CONSP (x), Qlistp, y) #define lisp_h_CHECK_NUMBER(x) CHECK_TYPE (INTEGERP (x), Qintegerp, x) #define lisp_h_CHECK_SYMBOL(x) CHECK_TYPE (SYMBOLP (x), Qsymbolp, x) #define lisp_h_CHECK_TYPE(ok, predicate, x) \ ((ok) ? (void) 0 : (void) wrong_type_argument (predicate, x)) #define lisp_h_CONSP(x) (XTYPE (x) == Lisp_Cons) #define lisp_h_EQ(x, y) (XLI (x) == XLI (y)) #define lisp_h_FLOATP(x) (XTYPE (x) == Lisp_Float) #define lisp_h_INTEGERP(x) ((XTYPE (x) & (Lisp_Int0 | ~Lisp_Int1)) == Lisp_Int0) #define lisp_h_MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker) #define lisp_h_MISCP(x) (XTYPE (x) == Lisp_Misc) #define lisp_h_NILP(x) EQ (x, Qnil) #define lisp_h_SET_SYMBOL_VAL(sym, v) \ (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value = (v)) #define lisp_h_SYMBOL_CONSTANT_P(sym) (XSYMBOL (sym)->constant) #define lisp_h_SYMBOL_VAL(sym) \ (eassert ((sym)->redirect == SYMBOL_PLAINVAL), (sym)->val.value) #define lisp_h_SYMBOLP(x) (XTYPE (x) == Lisp_Symbol) #define lisp_h_VECTORLIKEP(x) (XTYPE (x) == Lisp_Vectorlike) #define lisp_h_XCAR(c) XCONS (c)->car #define lisp_h_XCDR(c) XCONS (c)->u.cdr #define lisp_h_XCONS(a) \ (eassert (CONSP (a)), (struct Lisp_Cons *) XUNTAG (a, Lisp_Cons)) #define lisp_h_XHASH(a) XUINT (a) #define lisp_h_XPNTR(a) \ (SYMBOLP (a) ? XSYMBOL (a) : (void *) ((intptr_t) (XLI (a) & VALMASK))) #ifndef GC_CHECK_CONS_LIST # define lisp_h_check_cons_list() ((void) 0) #endif #if USE_LSB_TAG # define lisp_h_make_number(n) \ XIL ((EMACS_INT) (((EMACS_UINT) (n) << INTTYPEBITS) + Lisp_Int0)) # define lisp_h_XFASTINT(a) XINT (a) # define lisp_h_XINT(a) (XLI (a) >> INTTYPEBITS) # define lisp_h_XSYMBOL(a) \ (eassert (SYMBOLP (a)), \ (struct Lisp_Symbol *) ((uintptr_t) XLI (a) - Lisp_Symbol \ + (char *) lispsym)) # define lisp_h_XTYPE(a) ((enum Lisp_Type) (XLI (a) & ~VALMASK)) # define lisp_h_XUNTAG(a, type) ((void *) (intptr_t) (XLI (a) - (type))) #endif /* When compiling via gcc -O0, define the key operations as macros, as Emacs is too slow otherwise. To disable this optimization, compile with -DINLINING=false. */ #if (defined __NO_INLINE__ \ && ! defined __OPTIMIZE__ && ! defined __OPTIMIZE_SIZE__ \ && ! (defined INLINING && ! INLINING)) # define XLI(o) lisp_h_XLI (o) # define XIL(i) lisp_h_XIL (i) # define CHECK_LIST_CONS(x, y) lisp_h_CHECK_LIST_CONS (x, y) # define CHECK_NUMBER(x) lisp_h_CHECK_NUMBER (x) # define CHECK_SYMBOL(x) lisp_h_CHECK_SYMBOL (x) # define CHECK_TYPE(ok, predicate, x) lisp_h_CHECK_TYPE (ok, predicate, x) # define CONSP(x) lisp_h_CONSP (x) # define EQ(x, y) lisp_h_EQ (x, y) # define FLOATP(x) lisp_h_FLOATP (x) # define INTEGERP(x) lisp_h_INTEGERP (x) # define MARKERP(x) lisp_h_MARKERP (x) # define MISCP(x) lisp_h_MISCP (x) # define NILP(x) lisp_h_NILP (x) # define SET_SYMBOL_VAL(sym, v) lisp_h_SET_SYMBOL_VAL (sym, v) # define SYMBOL_CONSTANT_P(sym) lisp_h_SYMBOL_CONSTANT_P (sym) # define SYMBOL_VAL(sym) lisp_h_SYMBOL_VAL (sym) # define SYMBOLP(x) lisp_h_SYMBOLP (x) # define VECTORLIKEP(x) lisp_h_VECTORLIKEP (x) # define XCAR(c) lisp_h_XCAR (c) # define XCDR(c) lisp_h_XCDR (c) # define XCONS(a) lisp_h_XCONS (a) # define XHASH(a) lisp_h_XHASH (a) # define XPNTR(a) lisp_h_XPNTR (a) # ifndef GC_CHECK_CONS_LIST # define check_cons_list() lisp_h_check_cons_list () # endif # if USE_LSB_TAG # define make_number(n) lisp_h_make_number (n) # define XFASTINT(a) lisp_h_XFASTINT (a) # define XINT(a) lisp_h_XINT (a) # define XSYMBOL(a) lisp_h_XSYMBOL (a) # define XTYPE(a) lisp_h_XTYPE (a) # define XUNTAG(a, type) lisp_h_XUNTAG (a, type) # endif #endif /* Define NAME as a lisp.h inline function that returns TYPE and has arguments declared as ARGDECLS and passed as ARGS. ARGDECLS and ARGS should be parenthesized. Implement the function by calling lisp_h_NAME ARGS. */ /* lisp.h:423 */ #define LISP_MACRO_DEFUN(name, type, argdecls, args) \ INLINE type (name) argdecls { return lisp_h_##name args; } /* Lisp integers use 2 tags, to give them one extra bit, thus extending their range from, e.g., -2^28..2^28-1 to -2^29..2^29-1. */ /* lisp.h:437 */ #define INTMASK (EMACS_INT_MAX >> (INTTYPEBITS - 1)) /* Idea stolen from GDB. Pedantic GCC complains about enum bitfields, MSVC doesn't support them, and xlc and Oracle Studio c99 complain vociferously about them. */ /* lisp.h:443 */ #if (defined __STRICT_ANSI__ || defined _MSC_VER || defined __IBMC__ \ || (defined __SUNPRO_C && __STDC__)) #define ENUM_BF(TYPE) unsigned int #else #define ENUM_BF(TYPE) enum TYPE #endif /* lisp.h:451 */ enum Lisp_Type { /* Symbol. XSYMBOL (object) points to a struct Lisp_Symbol. */ Lisp_Symbol = 0, /* Miscellaneous. XMISC (object) points to a union Lisp_Misc, whose first member indicates the subtype. */ Lisp_Misc = 1, /* Integer. XINT (obj) is the integer value. */ Lisp_Int0 = 2, Lisp_Int1 = USE_LSB_TAG ? 6 : 3, /* String. XSTRING (object) points to a struct Lisp_String. The length of the string, and its contents, are stored therein. */ Lisp_String = 4, /* Vector of Lisp objects, or something resembling it. XVECTOR (object) points to a struct Lisp_Vector, which contains the size and contents. The size field also contains the type information, if it's not a real vector object. */ Lisp_Vectorlike = 5, /* Cons. XCONS (object) points to a struct Lisp_Cons. */ Lisp_Cons = USE_LSB_TAG ? 3 : 6, Lisp_Float = 7 }; /* This is the set of data types that share a common structure. The first member of the structure is a type code from this set. The enum values are arbitrary, but we'll use large numbers to make it more likely that we'll spot the error if a random word in memory is mistakenly interpreted as a Lisp_Misc. */ /* lisp.h:485 */ enum Lisp_Misc_Type { Lisp_Misc_Free = 0x5eab, Lisp_Misc_Marker, Lisp_Misc_Overlay, Lisp_Misc_Save_Value, /* Currently floats are not a misc type, but let's define this in case we want to change that. */ Lisp_Misc_Float, #ifdef HAVE_LTDL Lisp_Misc_Module, #endif /* This is not a type code. It is for range checking. */ Lisp_Misc_Limit }; /* If you want to define a new Lisp data type, here are some instructions. See the thread at http://lists.gnu.org/archive/html/emacs-devel/2012-10/msg00561.html for more info. First, there are already a couple of Lisp types that can be used if your new type does not need to be exposed to Lisp programs nor displayed to users. These are Lisp_Save_Value, a Lisp_Misc subtype; and PVEC_OTHER, a kind of vectorlike object. The former is suitable for temporarily stashing away pointers and integers in a Lisp object. The latter is useful for vector-like Lisp objects that need to be used as part of other objects, but which are never shown to users or Lisp code (search for PVEC_OTHER in xterm.c for an example). These two types don't look pretty when printed, so they are unsuitable for Lisp objects that can be exposed to users. To define a new data type, add one more Lisp_Misc subtype or one more pseudovector subtype. Pseudovectors are more suitable for objects with several slots that need to support fast random access, while Lisp_Misc types are for everything else. A pseudovector object provides one or more slots for Lisp objects, followed by struct members that are accessible only from C. A Lisp_Misc object is a wrapper for a C struct that can contain anything you like. Explicit freeing is discouraged for Lisp objects in general. But if you really need to exploit this, use Lisp_Misc (check free_misc in alloc.c to see why). There is no way to free a vectorlike object. To add a new pseudovector type, extend the pvec_type enumeration; to add a new Lisp_Misc, extend the Lisp_Misc_Type enumeration. For a Lisp_Misc, you will also need to add your entry to union Lisp_Misc (but make sure the first word has the same structure as the others, starting with a 16-bit member of the Lisp_Misc_Type enumeration and a 1-bit GC markbit) and make sure the overall size of the union is not increased by your addition. For a new pseudovector, it's highly desirable to limit the size of your data type by VBLOCK_BYTES_MAX bytes (defined in alloc.c). Otherwise you will need to change sweep_vectors (also in alloc.c). Then you will need to add switch branches in print.c (in print_object, to print your object, and possibly also in print_preprocess) and to alloc.c, to mark your object (in mark_object) and to free it (in gc_sweep). The latter is also the right place to call any code specific to your data type that needs to run when the object is recycled -- e.g., free any additional resources allocated for it that are not Lisp objects. You can even make a pointer to the function that frees the resources a slot in your object -- this way, the same object could be used to represent several disparate C structures. */ /* lisp.h:567 */ #ifdef CHECK_LISP_OBJECT_TYPE typedef struct { EMACS_INT i; } Lisp_Object; #define LISP_INITIALLY(i) {i} #undef CHECK_LISP_OBJECT_TYPE enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = true }; #else /* CHECK_LISP_OBJECT_TYPE */ /* If a struct type is not wanted, define Lisp_Object as just a number. */ typedef EMACS_INT Lisp_Object; #define LISP_INITIALLY(i) (i) enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = false }; #endif /* CHECK_LISP_OBJECT_TYPE */ /* lisp.h:582 */ /* lisp.h:612 */ INLINE bool STRINGP (Lisp_Object); /* lisp.h:621 */ INLINE void *(XUNTAG) (Lisp_Object, int); /* lisp.h:649 */ enum symbol_redirect { SYMBOL_PLAINVAL = 4, SYMBOL_VARALIAS = 1, SYMBOL_LOCALIZED = 2, SYMBOL_FORWARDED = 3 }; /* lisp.h:657 */ struct Lisp_Symbol { bool_bf gcmarkbit : 1; /* Indicates where the value can be found: 0 : it's a plain var, the value is in the `value' field. 1 : it's a varalias, the value is really in the `alias' symbol. 2 : it's a localized var, the value is in the `blv' object. 3 : it's a forwarding variable, the value is in `forward'. */ ENUM_BF (symbol_redirect) redirect : 3; /* Non-zero means symbol is constant, i.e. changing its value should signal an error. If the value is 3, then the var can be changed, but only by `defconst'. */ unsigned constant : 2; /* Interned state of the symbol. This is an enumerator from enum symbol_interned. */ unsigned interned : 2; /* True means that this variable has been explicitly declared special (with `defvar' etc), and shouldn't be lexically bound. */ bool_bf declared_special : 1; /* True if pointed to from purespace and hence can't be GC'd. */ bool_bf pinned : 1; /* The symbol's name, as a Lisp string. */ Lisp_Object name; /* Value of the symbol or Qunbound if unbound. Which alternative of the union is used depends on the `redirect' field above. */ union { Lisp_Object value; struct Lisp_Symbol *alias; struct Lisp_Buffer_Local_Value *blv; union Lisp_Fwd *fwd; } val; /* Function value of the symbol or Qnil if not fboundp. */ Lisp_Object function; /* The symbol's property list. */ Lisp_Object plist; /* Next symbol in obarray bucket, if the symbol is interned. */ struct Lisp_Symbol *next; }; /* lisp.h:710 */ #define EXFUN(fnname, maxargs) \ extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs /* Note that the weird token-substitution semantics of ANSI C makes this work for MANY and UNEVALLED. */ #define DEFUN_ARGS_MANY (ptrdiff_t, Lisp_Object *) #define DEFUN_ARGS_UNEVALLED (Lisp_Object) #define DEFUN_ARGS_0 (void) #define DEFUN_ARGS_1 (Lisp_Object) #define DEFUN_ARGS_2 (Lisp_Object, Lisp_Object) #define DEFUN_ARGS_3 (Lisp_Object, Lisp_Object, Lisp_Object) #define DEFUN_ARGS_4 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) #define DEFUN_ARGS_5 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ Lisp_Object) #define DEFUN_ARGS_6 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ Lisp_Object, Lisp_Object) #define DEFUN_ARGS_7 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ Lisp_Object, Lisp_Object, Lisp_Object) #define DEFUN_ARGS_8 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) /* Yield an integer that contains TAG along with PTR. */ #define TAG_PTR(tag, ptr) \ ((USE_LSB_TAG ? (tag) : (EMACS_UINT) (tag) << VALBITS) + (uintptr_t) (ptr)) /* Yield an integer that contains a symbol tag along with OFFSET. OFFSET should be the offset in bytes from 'lispsym' to the symbol. */ /* lisp.h:737 */ #define TAG_SYMOFFSET(offset) \ TAG_PTR (Lisp_Symbol, \ ((uintptr_t) (offset) >> (USE_LSB_TAG ? 0 : GCTYPEBITS))) /* lisp.h:754 */ /* FIXME: need to define Qt etc, EXFUNs from globals.h */ struct Lisp_Symbol alignas (GCALIGNMENT) lispsym[1131]; #define iQnil 0 #define Qnil builtin_lisp_symbol (iQnil) #define iQt 955 #define Qt builtin_lisp_symbol (iQt) EXFUN (Fprovide, 2); /* Convert a Lisp_Object to the corresponding EMACS_INT and vice versa. At the machine level, these operations are no-ops. */ /* lisp.h:758 */ LISP_MACRO_DEFUN (XLI, EMACS_INT, (Lisp_Object o), (o)) LISP_MACRO_DEFUN (XIL, Lisp_Object, (EMACS_INT i), (i)) /* In a pseudovector, the size field actually contains a word with one PSEUDOVECTOR_FLAG bit set, and one of the following values extracted with PVEC_TYPE_MASK to indicate the actual type. */ /* lisp.h:776 */ enum pvec_type { PVEC_NORMAL_VECTOR, PVEC_FREE, PVEC_PROCESS, PVEC_FRAME, PVEC_WINDOW, PVEC_BOOL_VECTOR, PVEC_BUFFER, PVEC_HASH_TABLE, PVEC_TERMINAL, PVEC_WINDOW_CONFIGURATION, PVEC_SUBR, PVEC_OTHER, /* These should be last, check internal_equal to see why. */ PVEC_COMPILED, PVEC_CHAR_TABLE, PVEC_SUB_CHAR_TABLE, PVEC_FONT /* Should be last because it's used for range checking. */ }; /* lisp.h:787 */ enum More_Lisp_Bits { /* For convenience, we also store the number of elements in these bits. Note that this size is not necessarily the memory-footprint size, but only the number of Lisp_Object fields (that need to be traced by GC). The distinction is used, e.g., by Lisp_Process, which places extra non-Lisp_Object fields at the end of the structure. */ PSEUDOVECTOR_SIZE_BITS = 12, PSEUDOVECTOR_SIZE_MASK = (1 << PSEUDOVECTOR_SIZE_BITS) - 1, /* To calculate the memory footprint of the pseudovector, it's useful to store the size of non-Lisp area in word_size units here. */ PSEUDOVECTOR_REST_BITS = 12, PSEUDOVECTOR_REST_MASK = (((1 << PSEUDOVECTOR_REST_BITS) - 1) << PSEUDOVECTOR_SIZE_BITS), /* Used to extract pseudovector subtype information. */ PSEUDOVECTOR_AREA_BITS = PSEUDOVECTOR_SIZE_BITS + PSEUDOVECTOR_REST_BITS, PVEC_TYPE_MASK = 0x3f << PSEUDOVECTOR_AREA_BITS }; /* Mask for the value (as opposed to the type bits) of a Lisp object. */ DEFINE_GDB_SYMBOL_BEGIN (EMACS_INT, VALMASK) /* lisp.h:827 */ # define VALMASK (USE_LSB_TAG ? - (1 << GCTYPEBITS) : VAL_MAX) DEFINE_GDB_SYMBOL_END (VALMASK) /* lisp.h:833 */ #if USE_LSB_TAG LISP_MACRO_DEFUN (make_number, Lisp_Object, (EMACS_INT n), (n)) LISP_MACRO_DEFUN (XINT, EMACS_INT, (Lisp_Object a), (a)) LISP_MACRO_DEFUN (XFASTINT, EMACS_INT, (Lisp_Object a), (a)) LISP_MACRO_DEFUN (XSYMBOL, struct Lisp_Symbol *, (Lisp_Object a), (a)) LISP_MACRO_DEFUN (XTYPE, enum Lisp_Type, (Lisp_Object a), (a)) LISP_MACRO_DEFUN (XUNTAG, void *, (Lisp_Object a, int type), (a, type)) #else /* ! USE_LSB_TAG */ /* Although compiled only if ! USE_LSB_TAG, the following functions also work when USE_LSB_TAG; this is to aid future maintenance when the lisp_h_* macros are eventually removed. */ /* Make a Lisp integer representing the value of the low order bits of N. */ INLINE Lisp_Object make_number (EMACS_INT n) { EMACS_INT int0 = Lisp_Int0; if (USE_LSB_TAG) { EMACS_UINT u = n; n = u << INTTYPEBITS; n += int0; } else { n &= INTMASK; n += (int0 << VALBITS); } return XIL (n); } /* Extract A's value as a signed integer. */ INLINE EMACS_INT XINT (Lisp_Object a) { EMACS_INT i = XLI (a); if (! USE_LSB_TAG) { EMACS_UINT u = i; i = u << INTTYPEBITS; } return i >> INTTYPEBITS; } /* Like XINT (A), but may be faster. A must be nonnegative. If ! USE_LSB_TAG, this takes advantage of the fact that Lisp integers have zero-bits in their tags. */ INLINE EMACS_INT XFASTINT (Lisp_Object a) { EMACS_INT int0 = Lisp_Int0; EMACS_INT n = USE_LSB_TAG ? XINT (a) : XLI (a) - (int0 << VALBITS); eassert (0 <= n); return n; } /* Extract A's value as a symbol. */ INLINE struct Lisp_Symbol * XSYMBOL (Lisp_Object a) { uintptr_t i = (uintptr_t) XUNTAG (a, Lisp_Symbol); if (! USE_LSB_TAG) i <<= GCTYPEBITS; void *p = (char *) lispsym + i; return p; } /* Extract A's type. */ INLINE enum Lisp_Type XTYPE (Lisp_Object a) { EMACS_UINT i = XLI (a); return USE_LSB_TAG ? i & ~VALMASK : i >> VALBITS; } /* Extract A's pointer value, assuming A's type is TYPE. */ INLINE void * XUNTAG (Lisp_Object a, int type) { intptr_t i = USE_LSB_TAG ? XLI (a) - type : XLI (a) & VALMASK; return (void *) i; } #endif /* ! USE_LSB_TAG */ /* lisp.h:920 */ /* lisp.h:975 */ INLINE struct Lisp_String * XSTRING (Lisp_Object a) { eassert (STRINGP (a)); return XUNTAG (a, Lisp_String); } /* lisp.h:1061 */ INLINE Lisp_Object make_lisp_symbol (struct Lisp_Symbol *sym) { Lisp_Object a = XIL (TAG_SYMOFFSET ((char *) sym - (char *) lispsym)); eassert (XSYMBOL (a) == sym); return a; } /* lisp.h:1070 */ INLINE Lisp_Object builtin_lisp_symbol (int index) { return make_lisp_symbol (lispsym + index); } /* See the macros in intervals.h. */ /* lisp.h:1149 */ typedef struct interval *INTERVAL; /* In a string or vector, the sign bit of the `size' is the gc mark bit. */ /* lisp.h:1233 */ struct GCALIGNED Lisp_String { ptrdiff_t size; ptrdiff_t size_byte; INTERVAL intervals; /* Text properties in this string. */ unsigned char *data; }; /* lisp.h:1285 */ INLINE unsigned char * SDATA (Lisp_Object string) { return XSTRING (string)->data; } INLINE char * SSDATA (Lisp_Object string) { /* Avoid "differ in sign" warnings. */ return (char *) SDATA (string); } /* Header of vector-like objects. This documents the layout constraints on vectors and pseudovectors (objects of PVEC_xxx subtype). It also prevents compilers from being fooled by Emacs's type punning: XSETPSEUDOVECTOR and PSEUDOVECTORP cast their pointers to struct vectorlike_header *, because when two such pointers potentially alias, a compiler won't incorrectly reorder loads and stores to their size fields. See Bug#8546. */ /* lisp.h:1344 */ struct vectorlike_header { /* The only field contains various pieces of information: - The MSB (ARRAY_MARK_FLAG) holds the gcmarkbit. - The next bit (PSEUDOVECTOR_FLAG) indicates whether this is a plain vector (0) or a pseudovector (1). - If PSEUDOVECTOR_FLAG is 0, the rest holds the size (number of slots) of the vector. - If PSEUDOVECTOR_FLAG is 1, the rest is subdivided into three fields: - a) pseudovector subtype held in PVEC_TYPE_MASK field; - b) number of Lisp_Objects slots at the beginning of the object held in PSEUDOVECTOR_SIZE_MASK field. These objects are always traced by the GC; - c) size of the rest fields held in PSEUDOVECTOR_REST_MASK and measured in word_size units. Rest fields may also include Lisp_Objects, but these objects usually needs some special treatment during GC. There are some exceptions. For PVEC_FREE, b) is always zero. For PVEC_BOOL_VECTOR and PVEC_SUBR, both b) and c) are always zero. Current layout limits the pseudovectors to 63 PVEC_xxx subtypes, 4095 Lisp_Objects in GC-ed area and 4095 word-sized other slots. */ ptrdiff_t size; }; /* This structure describes a built-in function. It is generated by the DEFUN macro only. defsubr makes it into a Lisp object. */ /* lisp.h:1670 */ struct Lisp_Subr { struct vectorlike_header header; union { Lisp_Object (*a0) (void); Lisp_Object (*a1) (Lisp_Object); Lisp_Object (*a2) (Lisp_Object, Lisp_Object); Lisp_Object (*a3) (Lisp_Object, Lisp_Object, Lisp_Object); Lisp_Object (*a4) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); Lisp_Object (*a5) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); Lisp_Object (*a6) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); Lisp_Object (*a7) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); Lisp_Object (*a8) (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); Lisp_Object (*aUNEVALLED) (Lisp_Object args); Lisp_Object (*aMANY) (ptrdiff_t, Lisp_Object *); } function; short min_args, max_args; const char *symbol_name; const char *intspec; Lisp_Object doc; }; INLINE struct Lisp_Save_Value *XSAVE_VALUE (Lisp_Object); /* Types of data which may be saved in a Lisp_Save_Value. */ /* lisp.h:2045 */ enum { SAVE_UNUSED, SAVE_INTEGER, SAVE_FUNCPOINTER, SAVE_POINTER, SAVE_OBJECT }; /* Number of bits needed to store one of the above values. */ enum { SAVE_SLOT_BITS = 3 }; /* Number of slots in a save value where save_type is nonzero. */ enum { SAVE_VALUE_SLOTS = 4 }; /* Bit-width and values for struct Lisp_Save_Value's save_type member. */ enum { SAVE_TYPE_BITS = SAVE_VALUE_SLOTS * SAVE_SLOT_BITS + 1 }; enum Lisp_Save_Type { SAVE_TYPE_INT_INT = SAVE_INTEGER + (SAVE_INTEGER << SAVE_SLOT_BITS), SAVE_TYPE_INT_INT_INT = (SAVE_INTEGER + (SAVE_TYPE_INT_INT << SAVE_SLOT_BITS)), SAVE_TYPE_OBJ_OBJ = SAVE_OBJECT + (SAVE_OBJECT << SAVE_SLOT_BITS), SAVE_TYPE_OBJ_OBJ_OBJ = SAVE_OBJECT + (SAVE_TYPE_OBJ_OBJ << SAVE_SLOT_BITS), SAVE_TYPE_OBJ_OBJ_OBJ_OBJ = SAVE_OBJECT + (SAVE_TYPE_OBJ_OBJ_OBJ << SAVE_SLOT_BITS), SAVE_TYPE_PTR_INT = SAVE_POINTER + (SAVE_INTEGER << SAVE_SLOT_BITS), SAVE_TYPE_PTR_OBJ = SAVE_POINTER + (SAVE_OBJECT << SAVE_SLOT_BITS), SAVE_TYPE_PTR_PTR = SAVE_POINTER + (SAVE_POINTER << SAVE_SLOT_BITS), SAVE_TYPE_FUNCPTR_PTR_OBJ = SAVE_FUNCPOINTER + (SAVE_TYPE_PTR_OBJ << SAVE_SLOT_BITS), /* This has an extra bit indicating it's raw memory. */ SAVE_TYPE_MEMORY = SAVE_TYPE_PTR_INT + (1 << (SAVE_TYPE_BITS - 1)) }; /* Special object used to hold a different values for later use. This is mostly used to package C integers and pointers to call record_unwind_protect when two or more values need to be saved. For example: ... struct my_data *md = get_my_data (); ptrdiff_t mi = get_my_integer (); record_unwind_protect (my_unwind, make_save_ptr_int (md, mi)); ... Lisp_Object my_unwind (Lisp_Object arg) { struct my_data *md = XSAVE_POINTER (arg, 0); ptrdiff_t mi = XSAVE_INTEGER (arg, 1); ... } If ENABLE_CHECKING is in effect, XSAVE_xxx macros do type checking of the saved objects and raise eassert if type of the saved object doesn't match the type which is extracted. In the example above, XSAVE_INTEGER (arg, 2) and XSAVE_OBJECT (arg, 0) are wrong because nothing was saved in slot 2 and slot 0 is a pointer. */ typedef void (*voidfuncptr) (void); /* lisp.h:2110 */ struct Lisp_Save_Value { ENUM_BF (Lisp_Misc_Type) type : 16; /* = Lisp_Misc_Save_Value */ bool_bf gcmarkbit : 1; unsigned spacer : 32 - (16 + 1 + SAVE_TYPE_BITS); /* V->data may hold up to SAVE_VALUE_SLOTS entries. The type of V's data entries are determined by V->save_type. E.g., if V->save_type == SAVE_TYPE_PTR_OBJ, V->data[0] is a pointer, V->data[1] is an integer, and V's other data entries are unused. If V->save_type == SAVE_TYPE_MEMORY, V->data[0].pointer is the address of a memory area containing V->data[1].integer potential Lisp_Objects. */ ENUM_BF (Lisp_Save_Type) save_type : SAVE_TYPE_BITS; union { void *pointer; voidfuncptr funcpointer; ptrdiff_t integer; Lisp_Object object; } data[SAVE_VALUE_SLOTS]; }; /* Return the type of V's Nth saved value. */ INLINE int save_type (struct Lisp_Save_Value *v, int n) { eassert (0 <= n && n < SAVE_VALUE_SLOTS); return (v->save_type >> (SAVE_SLOT_BITS * n) & ((1 << SAVE_SLOT_BITS) - 1)); } /* Get and set the Nth saved pointer. */ /* lisp.h:2143 */ INLINE void * XSAVE_POINTER (Lisp_Object obj, int n) { eassert (save_type (XSAVE_VALUE (obj), n) == SAVE_POINTER); return XSAVE_VALUE (obj)->data[n].pointer; } /* Define a built-in function for calling from Lisp. `lname' should be the name to give the function in Lisp, as a null-terminated C string. `fnname' should be the name of the function in C. By convention, it starts with F. `sname' should be the name for the C constant structure that records information on this function for internal use. By convention, it should be the same as `fnname' but with S instead of F. It's too bad that C macros can't compute this from `fnname'. `minargs' should be a number, the minimum number of arguments allowed. `maxargs' should be a number, the maximum number of arguments allowed, or else MANY or UNEVALLED. MANY means pass a vector of evaluated arguments, in the form of an integer number-of-arguments followed by the address of a vector of Lisp_Objects which contains the argument values. UNEVALLED means pass the list of unevaluated arguments `intspec' says how interactive arguments are to be fetched. If the string starts with a `(', `intspec' is evaluated and the resulting list is the list of arguments. If it's a string that doesn't start with `(', the value should follow the one of the doc string for `interactive'. A null string means call interactively with no arguments. `doc' is documentation for the user. */ /* This version of DEFUN declares a function prototype with the right arguments, so we can catch errors with maxargs at compile-time. */ /* lisp.h:2812 */ #ifdef _MSC_VER #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ Lisp_Object fnname DEFUN_ARGS_ ## maxargs ; \ static struct Lisp_Subr alignas (GCALIGNMENT) sname = \ { { (PVEC_SUBR << PSEUDOVECTOR_AREA_BITS) \ | (sizeof (struct Lisp_Subr) / sizeof (EMACS_INT)) }, \ { (Lisp_Object (__cdecl *)(void))fnname }, \ minargs, maxargs, lname, intspec, 0}; \ Lisp_Object fnname #else /* not _MSC_VER */ #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ static struct Lisp_Subr alignas (GCALIGNMENT) sname = \ { { PVEC_SUBR << PSEUDOVECTOR_AREA_BITS }, \ { .a ## maxargs = fnname }, \ minargs, maxargs, lname, intspec, 0}; \ Lisp_Object fnname #endif /* defsubr (Sname); is how we define the symbol for function `name' at start-up time. */ /* lisp.h:2839 */ extern void defsubr (struct Lisp_Subr *); /* lisp.h:3777 */ extern Lisp_Object make_string (const char *, ptrdiff_t); /* lisp.h:3881 */ extern Lisp_Object make_save_ptr (void *); /* Defined in lread.c. */ /* lisp.h:3960 */ extern Lisp_Object intern_1 (const char *, ptrdiff_t); /* lisp.h:3987 */ INLINE Lisp_Object intern (const char *str) { return intern_1 (str, strlen (str)); } /* end of file */ ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 1:02 ` Stephen Leake @ 2015-02-15 17:32 ` Eli Zaretskii 2015-02-15 19:09 ` Stephen Leake 2015-02-15 19:30 ` Stefan Monnier 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-15 17:32 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel > From: Stephen Leake <stephen_leake@stephe-leake.org> > Date: Sat, 14 Feb 2015 19:02:48 -0600 > > I took a stab at creating emacs_module_api.h; attached. > > To do this, I replaced "#include <lisp.h>" > in modules/curl/curl.c with "#include <emacs_modules_api.h>", and copied > stuff from lisp.h and other headers to emacs_module_api.h until it > compiled. Note the FIXMEs; I could not figure out what was going on in > some places, so I just kludged it for now. Thanks. I started to write comments to that file, but gave up in despair. My overall conclusion from reviewing it is that, if we want the tightly-coupled version of modules, we might as well compile them as any other C source file in the Emacs tree, i.e. we could simply include lisp.h in its entirety, and all the other headers that it pulls in. I see no other workable alternative that would let modules use Lisp objects transparently (as opposed to using them as opaque objects), call Lisp primitives directly like we do in Emacs sources, etc. > > This already presents at least 2 problems. The first is 32- vs > > 64-bit issues. We need some way of checking that a 32-bit module > > isn't loaded by a 64-bit Emacs, and vice versa. > Good point. That's a special case of "don't load a module compiled for > processor X in an Emacs compiled for processor Y". gnu binutils has > facilities for that. Not sure how Binutils could help here. AFAIK, dlopen and dlsym (and their equivalents) don't invoke Binutils on any platform. > > The other problem is more serious: Emacs can be built with or > > without --check-lisp-object-type, and with or without --wide-int; > > how will the module know which implementation to use? > > Similar check when the module is loaded. Which means we need some > metainfo for each module, and a standard function to retrieve it. That "metainfo", whatever it will be, will also have to support compilation of modules: we need to know at compile time what values of USE_LSB_TAG, ENABLE_CHECKING, WIDE_EMACS_INT, optimization flags, etc. were used when Emacs was built, because those affect the layout of objects inside Emacs and also the availability of certain functions in the Emacs binary. > > . Functions to access values of Lisp objects. We shouldn't rely on C > > macros like XINT and XWINDOW for that, because macros track too > > closely the internals of each object. So I propose to use > > functions that will be exposed via the API. > > If we follow Stefan's suggestion, then either this function approach is > not viable, or we need another #ifdef for module vs emacs. If we don't use the function approach, we can only have modules that are tightly coupled with the version of Emacs for which they were written and compiled. We have no hope of binary compatibility with other versions of Emacs, except by sheer luck, and even source-level compatibility will be a challenge. > > They are currently written as if the code were an integral part of > > Emacs on one of the Emacs C files. Going that way means that modules > > will have to be recompiled from sources for each Emacs version, and > > practically will have to live in the Emacs tree. Maybe this is what we > > want, I don't know. > > This is the model I had in mind. Since I need max speed with mixed > Ada/lisp code, I need tight integration with the core. The people who > need that speed for Ada mode will simply have to recompile the module > for each Emacs release; they are coders, so that's not a problem. Being an Ada programmer (or even a C programmer) doesn't necessarily mean you know how to fix compile- and link-time problems with Emacs. You've just bumped into that yourself. In practice, I think this means maintainers of modules will have to adapt their modules to each Emacs version, and perhaps also keep several branches, one each for every version they want to support. > Rather than splitting out emacs_module_api.h from lisp.h, we could add > __declspec(dllexport) to a subset of the functions in lisp.h; I suspect > that will be a small number. What for? If we are going to expose most or all of lisp.h to modules, we are actually saying that all of Emacs internals should be exposed as well, so all of the lisp.h stuff should be externally visible, as it is used all over the place in Emacs sources, and modules will want to be able to do the same, under the "tightly-coupled" concept. > Is there an equivalent on Linux (I don't recall ever seeing one)? You want '__attribute__((visibility ("default")))', and you want to use -fvisibility=hidden on the command line. See https://gcc.gnu.org/wiki/Visibility But this looks futile wrt lisp.h, see above. Perhaps we could use that for other public functions in other headers, but I expect that paradigm to collapse very quickly, since modules will want to call Lisp primitives directly, not through funcall. Look at the modules already on the branch: they include buffer.h and character.h, and call stuff like Fgethash, Fputhash, and Fmake_hash_table. How much time will pass before we see modules call Finsert_file_contents, Fmake_frame, and Fredisplay? How can we explain to module developers that they need to go through funcall? And then "more internal" internals will quickly follow: scan_words, for example, or recenter_overlay_lists. It's a slippery slope, but I don't see how we could prevent the slip if we are willing to go with "tightly-coupled" modules. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 17:32 ` Eli Zaretskii @ 2015-02-15 19:09 ` Stephen Leake 2015-02-15 19:27 ` implementing curl module with opaque emacs types Stephen Leake 2015-02-15 19:28 ` Dynamic loading progress Eli Zaretskii 0 siblings, 2 replies; 765+ messages in thread From: Stephen Leake @ 2015-02-15 19:09 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Stephen Leake <stephen_leake@stephe-leake.org> >> Date: Sat, 14 Feb 2015 19:02:48 -0600 >> >> I took a stab at creating emacs_module_api.h; attached. >> >> To do this, I replaced "#include <lisp.h>" >> in modules/curl/curl.c with "#include <emacs_modules_api.h>", and copied >> stuff from lisp.h and other headers to emacs_module_api.h until it >> compiled. Note the FIXMEs; I could not figure out what was going on in >> some places, so I just kludged it for now. > > Thanks. > > I started to write comments to that file, but gave up in despair. My > overall conclusion from reviewing it is that, if we want the > tightly-coupled version of modules, we might as well compile them as > any other C source file in the Emacs tree, i.e. we could simply > include lisp.h in its entirety, and all the other headers that it > pulls in. I see no other workable alternative that would let modules > use Lisp objects transparently (as opposed to using them as opaque > objects), call Lisp primitives directly like we do in Emacs sources, > etc. I agree. >> > This already presents at least 2 problems. The first is 32- vs >> > 64-bit issues. We need some way of checking that a 32-bit module >> > isn't loaded by a 64-bit Emacs, and vice versa. > >> Good point. That's a special case of "don't load a module compiled for >> processor X in an Emacs compiled for processor Y". gnu binutils has >> facilities for that. > > Not sure how Binutils could help here. AFAIK, dlopen and dlsym (and > their equivalents) don't invoke Binutils on any platform. I was thinking Emacs could invoke some binutils function to query the .dll for this info, before calling dlopen. >> > The other problem is more serious: Emacs can be built with or >> > without --check-lisp-object-type, and with or without --wide-int; >> > how will the module know which implementation to use? >> >> Similar check when the module is loaded. Which means we need some >> metainfo for each module, and a standard function to retrieve it. > > That "metainfo", whatever it will be, will also have to support > compilation of modules: we need to know at compile time what values of > USE_LSB_TAG, ENABLE_CHECKING, WIDE_EMACS_INT, optimization flags, > etc. were used when Emacs was built, because those affect the layout > of objects inside Emacs and also the availability of certain functions > in the Emacs binary. Right. One solution is to only distribute source, and provide an elisp function 'module-make' (suggested by Stefan) that provides command-line options to a module makefile for all of those settings. >> > . Functions to access values of Lisp objects. We shouldn't rely on C >> > macros like XINT and XWINDOW for that, because macros track too >> > closely the internals of each object. So I propose to use >> > functions that will be exposed via the API. >> >> If we follow Stefan's suggestion, then either this function approach is >> not viable, or we need another #ifdef for module vs emacs. > > If we don't use the function approach, we can only have modules that > are tightly coupled with the version of Emacs for which they were > written and compiled. We have no hope of binary compatibility with > other versions of Emacs, except by sheer luck, and even source-level > compatibility will be a challenge. Right. >> > They are currently written as if the code were an integral part of >> > Emacs on one of the Emacs C files. Going that way means that modules >> > will have to be recompiled from sources for each Emacs version, and >> > practically will have to live in the Emacs tree. Maybe this is what we >> > want, I don't know. >> >> This is the model I had in mind. Since I need max speed with mixed >> Ada/lisp code, I need tight integration with the core. The people who >> need that speed for Ada mode will simply have to recompile the module >> for each Emacs release; they are coders, so that's not a problem. > > Being an Ada programmer (or even a C programmer) doesn't necessarily > mean you know how to fix compile- and link-time problems with Emacs. > You've just bumped into that yourself. Yes, and I'm becomming more sympathetic to your point of view :). > In practice, I think this means maintainers of modules will have to > adapt their modules to each Emacs version, and perhaps also keep > several branches, one each for every version they want to support. Yes, that was my plan. I do that now at the elisp level. >> Rather than splitting out emacs_module_api.h from lisp.h, we could add >> __declspec(dllexport) to a subset of the functions in lisp.h; I suspect >> that will be a small number. > > What for? Mostly just to get a confirmed list of the functions that curl.c currently calls. But I guess the link-time errors I started with is good enough for that. So let's take a stab at something closer to your approach. I'm not familiar with the idioms for making an opaque type in C; would that just be a pointer to void? something like: typedef void* Lisp_Object_Ptr; -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* implementing curl module with opaque emacs types 2015-02-15 19:09 ` Stephen Leake @ 2015-02-15 19:27 ` Stephen Leake 2015-02-15 19:47 ` Eli Zaretskii 2015-02-17 19:33 ` Stephen Leake 2015-02-15 19:28 ` Dynamic loading progress Eli Zaretskii 1 sibling, 2 replies; 765+ messages in thread From: Stephen Leake @ 2015-02-15 19:27 UTC (permalink / raw) To: emacs-devel Stephen Leake <stephen_leake@stephe-leake.org> writes: > So let's take a stab at something closer to your approach. > > I'm not familiar with the idioms for making an opaque type in C; would > that just be a pointer to void? something like: > > typedef void* Lisp_Object_Ptr; Here is the list of Emacs functions that curl.c currently uses Fprovide SSDATA XSAVE_POINTER builtin_lisp_symbol (for Qnil) defsubr intern make_string We can either implement these in a new version of emacs_module_api.h/.c, or rewrite curl.c to not use them. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: implementing curl module with opaque emacs types 2015-02-15 19:27 ` implementing curl module with opaque emacs types Stephen Leake @ 2015-02-15 19:47 ` Eli Zaretskii 2015-02-17 19:33 ` Stephen Leake 1 sibling, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-02-15 19:47 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel > From: Stephen Leake <stephen_leake@stephe-leake.org> > Date: Sun, 15 Feb 2015 13:27:40 -0600 > > Here is the list of Emacs functions that curl.c currently uses > > Fprovide > SSDATA > XSAVE_POINTER > builtin_lisp_symbol (for Qnil) > defsubr > intern > make_string It also uses XSAVE_VALUE (called by XSAVE_POINTER) and save_type and die, indirectly via eassert, when ENABLE_CHECKING is defined. Btw, its use of make_string is incorrect: it should use make_unibyte_string string and then decode it. Which will require more functions. Likewise with SSDATA: the string that is used as a URL should be encoded before it is passed to libcurl functions. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: implementing curl module with opaque emacs types 2015-02-15 19:27 ` implementing curl module with opaque emacs types Stephen Leake 2015-02-15 19:47 ` Eli Zaretskii @ 2015-02-17 19:33 ` Stephen Leake 1 sibling, 0 replies; 765+ messages in thread From: Stephen Leake @ 2015-02-17 19:33 UTC (permalink / raw) To: emacs-devel [-- Attachment #1: Type: text/plain, Size: 2049 bytes --] Stephen Leake <stephen_leake@stephe-leake.org> writes: > Stephen Leake <stephen_leake@stephe-leake.org> writes: > >> So let's take a stab at something closer to your approach. >> >> I'm not familiar with the idioms for making an opaque type in C; would >> that just be a pointer to void? something like: >> >> typedef void* Lisp_Object_Ptr; > > Here is the list of Emacs functions that curl.c currently uses > > Fprovide > SSDATA > XSAVE_POINTER > builtin_lisp_symbol (for Qnil) > defsubr > intern > make_string > > We can either implement these in a new version of emacs_module_api.h/.c, > or rewrite curl.c to not use them. Attached is a first attempt at emacs_module_api.h for this. The only change in curl.c is: -#include <config.h> -#include <lisp.h> +/* #include <config.h> */ +/* #include <lisp.h> */ +#include "emacs_modules_api.h" This gives compilation errors: curl.c: In function 'init': curl.c:113:13: error: 'Scurl_make' undeclared (first use in this function) defsubr (&Scurl_make); ^ curl.c:113:13: note: each undeclared identifier is reported only once for each function it appears in curl.c:114:13: error: 'Scurl_fetch_url' undeclared (first use in this function) defsubr (&Scurl_fetch_url); ^ curl.c:115:13: error: 'Scurl_content' undeclared (first use in this function) defsubr (&Scurl_content); ^ curl.c:116:13: error: 'Scurl_free' undeclared (first use in this function) defsubr (&Scurl_free); ^ Makefile:14: recipe for target 'curl.o' failed This is because I deleted the declaration of 'sname' from the DEFUN macro, because I couldn't figure out how to implement it simply. It seems EXFUN is redundant with the first part of DEFUN, so I'm not sure why the EXFUN statments are in curl.c. So we either need a lisp wrapper to declare the module functions, with some way to lookup the EXFUN symbols to set the function values, or we need to implement a C function (not macro) that creates the struct for defsubr. -- -- Stephe [-- Attachment #2: emacs_modules_api.h --] [-- Type: application/octet-stream, Size: 3889 bytes --] /* Emacs modules API */ #ifdef WINDOWSNT # ifdef emacs /* compiling emacs */ # define EMACS_EXPORT __declspec(dllexport) # else /* compiling a module */ # define EMACS_EXPORT __declspec(dllimport) # endif #else /* non-Windows OS */ # define EMACS_EXPORT __attribute__((visibility ("default"))) #endif #include <stdint.h> #include <stdbool.h> /* lisp.h:87 */ #ifndef EMACS_INT_MAX # if INTPTR_MAX <= 0 # error "INTPTR_MAX misconfigured" # elif INTPTR_MAX <= INT_MAX >> NONPOINTER_BITS && !defined WIDE_EMACS_INT typedef int EMACS_INT; typedef unsigned int EMACS_UINT; # define EMACS_INT_MAX INT_MAX # define pI "" # elif INTPTR_MAX <= LONG_MAX >> NONPOINTER_BITS && !defined WIDE_EMACS_INT typedef long int EMACS_INT; typedef unsigned long EMACS_UINT; # define EMACS_INT_MAX LONG_MAX # define pI "l" /* Check versus LLONG_MAX, not LLONG_MAX >> NONPOINTER_BITS. In theory this is not safe, but in practice it seems to be OK. */ # elif INTPTR_MAX <= LLONG_MAX typedef long long int EMACS_INT; typedef unsigned long long int EMACS_UINT; # define EMACS_INT_MAX LLONG_MAX # define pI "ll" # else # error "INTPTR_MAX too large" # endif #endif /* lisp.h:567 */ #ifdef CHECK_LISP_OBJECT_TYPE typedef struct { EMACS_INT i; } Lisp_Object; #define LISP_INITIALLY(i) {i} #undef CHECK_LISP_OBJECT_TYPE enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = true }; #else /* CHECK_LISP_OBJECT_TYPE */ /* If a struct type is not wanted, define Lisp_Object as just a number. */ typedef EMACS_INT Lisp_Object; #define LISP_INITIALLY(i) (i) enum CHECK_LISP_OBJECT_TYPE { CHECK_LISP_OBJECT_TYPE = false }; #endif /* CHECK_LISP_OBJECT_TYPE */ /* lisp.h:582 */ /* lisp.h:612 */ EMACS_EXPORT bool STRINGP (Lisp_Object); /* lisp.h:710 */ #define EXFUN(fnname, maxargs) \ extern Lisp_Object fnname DEFUN_ARGS_ ## maxargs /* Note that the weird token-substitution semantics of ANSI C makes this work for MANY and UNEVALLED. */ #define DEFUN_ARGS_MANY (ptrdiff_t, Lisp_Object *) #define DEFUN_ARGS_UNEVALLED (Lisp_Object) #define DEFUN_ARGS_0 (void) #define DEFUN_ARGS_1 (Lisp_Object) #define DEFUN_ARGS_2 (Lisp_Object, Lisp_Object) #define DEFUN_ARGS_3 (Lisp_Object, Lisp_Object, Lisp_Object) #define DEFUN_ARGS_4 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) #define DEFUN_ARGS_5 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ Lisp_Object) #define DEFUN_ARGS_6 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ Lisp_Object, Lisp_Object) #define DEFUN_ARGS_7 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ Lisp_Object, Lisp_Object, Lisp_Object) #define DEFUN_ARGS_8 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object, \ Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object) /* lisp.h:754 */ /* FIXME: need to define Qt etc, EXFUNs from globals.h */ #define iQnil 0 #define Qnil builtin_lisp_symbol (iQnil) #define iQt 955 #define Qt builtin_lisp_symbol (iQt) EXFUN (Fprovide, 2); /* lisp.h:1070 */ EMACS_EXPORT Lisp_Object builtin_lisp_symbol (int index); /* lisp.h:1285 */ EMACS_EXPORT unsigned char *SDATA (Lisp_Object string); EMACS_EXPORT char *SSDATA (Lisp_Object string); /* lisp.h:2143 */ EMACS_EXPORT void * XSAVE_POINTER (Lisp_Object obj, int n); /* lisp.h:2812 */ /* FIXME: not clear how to declare sname here. */ #define DEFUN(lname, fnname, sname, minargs, maxargs, intspec, doc) \ Lisp_Object fnname DEFUN_ARGS_ ## maxargs ;\ Lisp_Object fnname /* lisp.h:2839 */ struct Lisp_Subr; EMACS_EXPORT extern void defsubr (struct Lisp_Subr *); /* lisp.h:3777 */ EMACS_EXPORT extern Lisp_Object make_string (const char *, ptrdiff_t); /* lisp.h:3882 */ EMACS_EXPORT extern Lisp_Object make_save_ptr (void *); /* lisp.h:3987 */ Lisp_Object intern (const char *str); /* end of file */ ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 19:09 ` Stephen Leake 2015-02-15 19:27 ` implementing curl module with opaque emacs types Stephen Leake @ 2015-02-15 19:28 ` Eli Zaretskii 1 sibling, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-02-15 19:28 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel > From: Stephen Leake <stephen_leake@stephe-leake.org> > Date: Sun, 15 Feb 2015 13:09:25 -0600 > > > That "metainfo", whatever it will be, will also have to support > > compilation of modules: we need to know at compile time what values of > > USE_LSB_TAG, ENABLE_CHECKING, WIDE_EMACS_INT, optimization flags, > > etc. were used when Emacs was built, because those affect the layout > > of objects inside Emacs and also the availability of certain functions > > in the Emacs binary. > > Right. > > One solution is to only distribute source, and provide an elisp function > 'module-make' (suggested by Stefan) that provides command-line options > to a module makefile for all of those settings. That's a beginning, but it cannot be all there is to, because modules should be distributable in binary form as well, at least some Linux distributions will probably want that. > So let's take a stab at something closer to your approach. > > I'm not familiar with the idioms for making an opaque type in C; would > that just be a pointer to void? something like: > > typedef void* Lisp_Object_Ptr; I'd go with typedef intmax_t Lisp_Object; This should be wide enough to hold both a pointer and the widest integer type, although I think its being wide enough for a pointer is not guaranteed by the C standard. Another suggestion, from Stefan, was to use EMACS_INT, but I'm not sure we will be able to define it correctly without dragging in too much stuff from lisp.h that is used there to define EMACS_INT. Maybe we should have a separate definition of EMACS_INT for modules. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 1:02 ` Stephen Leake 2015-02-15 17:32 ` Eli Zaretskii @ 2015-02-15 19:30 ` Stefan Monnier 2015-02-16 15:25 ` Stephen Leake 1 sibling, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-02-15 19:30 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel > This is the model I had in mind. Since I need max speed with mixed > Ada/lisp code, I need tight integration with the core. The people who The non-tight integration will mostly impact uses of things like CONSP, XCAR, XCDR, ... but I'm far from convinced that making those go through function calls would slow you down enough to make much of a difference. Of course, we should provide functions to get efficient access to the buffer text, along the lines of INC_BOTH, and FETCH_CHAR. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 19:30 ` Stefan Monnier @ 2015-02-16 15:25 ` Stephen Leake 2015-02-16 19:02 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Stephen Leake @ 2015-02-16 15:25 UTC (permalink / raw) To: emacs-devel Stefan Monnier <monnier@IRO.UMontreal.CA> writes: >> This is the model I had in mind. Since I need max speed with mixed >> Ada/lisp code, I need tight integration with the core. The people who > > The non-tight integration will mostly impact uses of things like CONSP, > XCAR, XCDR, ... but I'm far from convinced that making those go through > function calls would slow you down enough to make much of a > difference. Ok. I'm willing to go with a non-tight implementation and see how fast it is. > Of course, we should provide functions to get efficient access to the > buffer text, along the lines of INC_BOTH, and FETCH_CHAR. Yes, the parser does need efficient access to the buffer text. Although one option is to keep the current elisp lexer, and only pass tokens to the module parser. Lots of things to benchmark :). -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-16 15:25 ` Stephen Leake @ 2015-02-16 19:02 ` Stefan Monnier 2015-04-20 23:21 ` Ted Zlatanov 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-02-16 19:02 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel > Yes, the parser does need efficient access to the buffer text. This is very important, IMHO, because that's one of the most compelling reasons to use modules instead of subprocesses: it allows much faster uptodate access to buffer's contents. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-16 19:02 ` Stefan Monnier @ 2015-04-20 23:21 ` Ted Zlatanov 2015-04-21 14:06 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Ted Zlatanov @ 2015-04-20 23:21 UTC (permalink / raw) To: emacs-devel On Mon, 16 Feb 2015 14:02:45 -0500 Stefan Monnier <monnier@IRO.UMontreal.CA> wrote: >> Yes, the parser does need efficient access to the buffer text. SM> This is very important, IMHO, because that's one of the most compelling SM> reasons to use modules instead of subprocesses: it allows much faster SM> uptodate access to buffer's contents. Perhaps we should move on with "pure data" modules and implement "buffer interaction" modules later? I see the utility, but would love to get something basic in place for the common cases like parsing data. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-04-20 23:21 ` Ted Zlatanov @ 2015-04-21 14:06 ` Stefan Monnier 2015-04-21 14:19 ` Ted Zlatanov 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-04-21 14:06 UTC (permalink / raw) To: emacs-devel > Perhaps we should move on with "pure data" modules and implement "buffer > interaction" modules later? It's definitely not a requirement before it can be installed into master. My criterion for installation into master is basically that the probability we'll soon reimplement it differently is sufficiently low (and for the code to be clean enough). Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-04-21 14:06 ` Stefan Monnier @ 2015-04-21 14:19 ` Ted Zlatanov 0 siblings, 0 replies; 765+ messages in thread From: Ted Zlatanov @ 2015-04-21 14:19 UTC (permalink / raw) To: emacs-devel On Tue, 21 Apr 2015 10:06:35 -0400 Stefan Monnier <monnier@IRO.UMontreal.CA> wrote: >> Perhaps we should move on with "pure data" modules and implement "buffer >> interaction" modules later? SM> It's definitely not a requirement before it can be installed into SM> master. My criterion for installation into master is basically that the SM> probability we'll soon reimplement it differently is sufficiently low SM> (and for the code to be clean enough). Thanks. I'll concentrate on testing the simple "pure data" cases and see if a usable general data access model can emerge from that. If not, we'll figure out what works... Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 19:12 ` Eli Zaretskii 2015-02-14 19:25 ` Eli Zaretskii 2015-02-15 1:02 ` Stephen Leake @ 2015-02-15 9:21 ` Stephen J. Turnbull 2015-02-15 17:34 ` Eli Zaretskii 2 siblings, 1 reply; 765+ messages in thread From: Stephen J. Turnbull @ 2015-02-15 9:21 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, Stefan Monnier, emacs-devel Eli Zaretskii writes: > It looks like modules need: > > . A function to replace the DEFUN macro and the related defsubr call. Aha, so you already figured this out for yourself. > . Some definition of Lisp_Object > > This already presents at least 2 problems. The first is 32- vs > 64-bit issues. We need some way of checking that a 32-bit module > isn't loaded by a 64-bit Emacs, and vice versa. > > The other problem is more serious: Emacs can be built with or > without --check-lisp-object-type, and with or without --wide-int; > how will the module know which implementation to use? XEmacs builds a separate compiler driver ellcc that knows how to build modules of the same configuration. > Perhaps the solution is to make Lisp_Object an opaque data type for > the modules, and not use the definition we have on lisp.h. I don't know how you identify type of objects, but since you only have a couple of tag bits left, I have to assume you use a header word of some kind. In XEmacs the header word is a pointer to a table of functions that define the common functionality of Lisp objects used by the interpreter and the virtual machines. Whether a method table pointer or an enum, that header word is pretty much the only thing that's going to be common to all types. Seems to me that's pretty close to opaque already. > . Functions to access values of Lisp objects. Not values, attributes. You don't want to just unbox the Lisp object and give modules access to internals. Rather, each object type should export a specific API in the form of accessors and mutators for its Lisp-visible attributes. This is what XEmacs already does, it's what Python does, and it's those two examples that give me the confidence that it will work for Emacs too. Sounds like it will be a pile of work, but you don't have to convert all types immediately. > . Functions to create Lisp objects and/or set their values. Again, > we shouldn't rely on the likes of XSETCONS. There should be a > function make_FOO for each object type FOO. This includes creating > symbols, so 'intern' should not be needed by modules. `intern' *is* the creation function for symbols. Uninterned symbols are hardly useful for modules; they already have a private namespace. > . A function to create a Lisp object that is a container for a C > struct or pointer. > > The above means that most of the C source files under modules/ should > be thoroughly rewritten. Sounds like a good idea to me. Wouldn't hurt if you rewrote most of the C source under src/ that way too. ;-) ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 9:21 ` Stephen J. Turnbull @ 2015-02-15 17:34 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-02-15 17:34 UTC (permalink / raw) To: Stephen J. Turnbull; +Cc: eggert, monnier, emacs-devel > From: "Stephen J. Turnbull" <stephen@xemacs.org> > Cc: Stefan Monnier <monnier@iro.umontreal.ca>, > eggert@cs.ucla.edu, > emacs-devel@gnu.org > Date: Sun, 15 Feb 2015 18:21:54 +0900 > > > . Some definition of Lisp_Object > > > > This already presents at least 2 problems. The first is 32- vs > > 64-bit issues. We need some way of checking that a 32-bit module > > isn't loaded by a 64-bit Emacs, and vice versa. > > > > The other problem is more serious: Emacs can be built with or > > without --check-lisp-object-type, and with or without --wide-int; > > how will the module know which implementation to use? > > XEmacs builds a separate compiler driver ellcc that knows how to build > modules of the same configuration. That won't support binary distributions of modules, would it? > > Perhaps the solution is to make Lisp_Object an opaque data type for > > the modules, and not use the definition we have on lisp.h. > > I don't know how you identify type of objects, but since you only have > a couple of tag bits left, I have to assume you use a header word of > some kind. In XEmacs the header word is a pointer to a table of > functions that define the common functionality of Lisp objects used by > the interpreter and the virtual machines. Whether a method table > pointer or an enum, that header word is pretty much the only thing > that's going to be common to all types. Seems to me that's pretty > close to opaque already. Making a Lisp_Object opaque, one way or the other, is easy. Getting people to accept that it will be opaque is harder. I posted my suggestion to try to convince that this is the way to go, but I'm not holding my breath, frankly. > > . Functions to access values of Lisp objects. > > Not values, attributes. I don't think the difference matters for the purposes of this discussion. The intent is to allow extracting a C int from Emacs integer, a C double from a Lisp float, a C char array from a Lisp string, a pointer to buffer text for buffers, etc. > You don't want to just unbox the Lisp object and give modules access > to internals. Rather, each object type should export a specific API > in the form of accessors and mutators for its Lisp-visible > attributes. I don't think modules will settle for using only the Lisp attributes, they would like access to C attributes as well. > > The above means that most of the C source files under modules/ should > > be thoroughly rewritten. > > Sounds like a good idea to me. Wouldn't hurt if you rewrote most of > the C source under src/ that way too. ;-) I'm not holding my breath. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-10 6:58 ` Paul Eggert 2015-02-10 20:40 ` Stefan Monnier @ 2015-02-11 9:19 ` Aurélien Aptel 2015-02-11 9:43 ` Aurélien Aptel 2015-02-11 13:26 ` Paul Eggert 1 sibling, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-02-11 9:19 UTC (permalink / raw) To: Paul Eggert; +Cc: Stephen Leake, Emacs development discussions On Tue, Feb 10, 2015 at 7:58 AM, Paul Eggert <eggert@cs.ucla.edu> wrote: > Though this raises a related issue: as I understand it currently modules > must never refer to any Qxxx symbols (other than Qnil), since these symbols > may have different values in different Emacs implementations. And this > includes any macros or inline functions the modules may invoke. For > example, a module must never call 'functionp', since 'functionp' is an > inline function that refers to Qt. I get it now, thanks :) I understand you made this change for performance reasons. Was it really a bottleneck though? I don't want to undermine your work and I probably don't know enough to begin with so bear with me. I am under the impression you implemented a clever change that wasn't critical but made the module implementation a lot harder. Reverting it or disabling it for modules might be a solution? What do you think? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-11 9:19 ` Aurélien Aptel @ 2015-02-11 9:43 ` Aurélien Aptel 2015-02-11 10:01 ` Aurélien Aptel 2015-02-11 15:35 ` Stefan Monnier 2015-02-11 13:26 ` Paul Eggert 1 sibling, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-02-11 9:43 UTC (permalink / raw) To: Paul Eggert; +Cc: Stephen Leake, Emacs development discussions In other news, I stayed up waaay too late yesterday but I got the destructor thing working! It's pushed on my branch. I added a new Lisp_Misc subtype called Lisp_Module which stores: - a module id - a void* user pointer - a function pointer to a destructor to release the resources of the user pointer There's a module_make_id() function that module can used to get a new unique id and a module_make_object(id, dtor, userp) that allocates a new module Lisp_Object. The destructor is called in by the GC in sweep_misc(), which sweeps the marker list (all misc subtypes use the marker list, maybe this should be documented somewhere). I've added a new source file for module functions in src/module.c. I've tried to ifdef'd everything properly: --without-ltdl has no runtime cost, as it should be. I have made an example module that uses this new lisp type in modules/memtest along with a ERT test. You can browse the commit here [1], it's relatively easy to follow. One thing I haven't checked is whether adding the Lisp_Module to the Lisp_Misc union changes its size (the existing comments say this is important). 1: https://github.com/aaptel/emacs-dynamic-module/commit/c59f2deaae99ca85b0a4fcdd53a3d8ed41d995cd ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-11 9:43 ` Aurélien Aptel @ 2015-02-11 10:01 ` Aurélien Aptel 2015-02-11 15:35 ` Stefan Monnier 1 sibling, 0 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-02-11 10:01 UTC (permalink / raw) To: Paul Eggert; +Cc: Stephen Leake, Emacs development discussions On Wed, Feb 11, 2015 at 10:43 AM, Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: > There's a module_make_id() function that module can used to get a new > unique id and a module_make_object(id, dtor, userp) that allocates a > new module Lisp_Object. I should clarify this. A module is expected to use the same id for all its objects. It will be used to make per-module predicates and probably other things. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-11 9:43 ` Aurélien Aptel 2015-02-11 10:01 ` Aurélien Aptel @ 2015-02-11 15:35 ` Stefan Monnier 2015-02-11 16:08 ` Aurélien Aptel 1 sibling, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-02-11 15:35 UTC (permalink / raw) To: Aurélien Aptel Cc: Paul Eggert, Stephen Leake, Emacs development discussions > I added a new Lisp_Misc subtype called Lisp_Module which stores: > - a module id > - a void* user pointer > - a function pointer to a destructor to release the resources of the > user pointer I think I got confused by the name: these objects don't represent modules, right (despite the name of their type)? They are objects created by a particular module (stored in the module-id). > One thing I haven't checked is whether adding the Lisp_Module to the > Lisp_Misc union changes its size (the existing comments say this is > important). The Lisp_Misc union is for objects with up to 5 "words" (or 6 "words" if you count the word that holds the header). Your objects have only 2 "words" (or 3 if you count the header where you added the "id"), so you're perfectly fine, with room to grow. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-11 15:35 ` Stefan Monnier @ 2015-02-11 16:08 ` Aurélien Aptel 2015-02-11 19:17 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-02-11 16:08 UTC (permalink / raw) To: Stefan Monnier; +Cc: Paul Eggert, Stephen Leake, Emacs development discussions On Wed, Feb 11, 2015 at 4:35 PM, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > I think I got confused by the name: these objects don't represent > modules, right (despite the name of their type)? They are objects > created by a particular module (stored in the module-id). Correct. I started with Lisp_Module_Object but thought it was redundant. We could make /module/ module objects too. Let's call them Module Descriptors to avoid any confusions. It could be a struct containing functions pointers for printing, moving, copying, freeing a module object, ... Module objects could then use a pointer to this struct as a module id. I don't have a lot of experience implementing programming languages, especially features like this. I don't want to rush things and end up with a complex C++-like system so feel free to comment if you think this is overengineering it. > The Lisp_Misc union is for objects with up to 5 "words" (or 6 "words" if > you count the word that holds the header). Your objects have only > 2 "words" (or 3 if you count the header where you added the "id"), so > you're perfectly fine, with room to grow. I'm not sure what "words" means here. Pointers are 64 bits wide on 64 bits systems, does this make a difference? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-11 16:08 ` Aurélien Aptel @ 2015-02-11 19:17 ` Stefan Monnier 0 siblings, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2015-02-11 19:17 UTC (permalink / raw) To: Aurélien Aptel Cc: Paul Eggert, Stephen Leake, Emacs development discussions >> I think I got confused by the name: these objects don't represent >> modules, right (despite the name of their type)? They are objects >> created by a particular module (stored in the module-id). > Correct. I started with Lisp_Module_Object but thought it was redundant. I think the undesirable part of this name is "module" ;-) At least, AFAICT, while this feature is introduced so that modules can use it, it is not directly dependent on modules. So, we could call it something else like "Lisp_Opaque_finalized_Object" (I'm sure you can all easily come up with an even longer name). >> The Lisp_Misc union is for objects with up to 5 "words" (or 6 "words" if >> you count the word that holds the header). Your objects have only >> 2 "words" (or 3 if you count the header where you added the "id"), so >> you're perfectly fine, with room to grow. > I'm not sure what "words" means here. It means "the natural size of things on the particular system". > Pointers are 64 bits wide on 64 bits systems, Right, so "words" are 64bit on such a system. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-11 9:19 ` Aurélien Aptel 2015-02-11 9:43 ` Aurélien Aptel @ 2015-02-11 13:26 ` Paul Eggert 1 sibling, 0 replies; 765+ messages in thread From: Paul Eggert @ 2015-02-11 13:26 UTC (permalink / raw) To: Aurélien Aptel; +Cc: Stephen Leake, Emacs development discussions Aurélien Aptel wrote: > disabling it for modules might be a solution? Yes, that's the idea. A kludgey way to do that right now is to have your module do this: #include <lisp.h> #undef Qfoo #undef Qbar ... with an #undef for every Qfoo symbol your code uses either directly or indirectly via macros or inline functions. Obviously we need something better than that, namely, we modify make-docfile.c so that instead of generating this: #define Qfoo builtin_lisp_symbol (iQfoo) it generates this: #ifndef EMACS_MODULE # define Qfoo builtin_lisp_symbol (iQfoo) #endif (and similarly for Qbar, etc.), and then you start your module this way: #define EMACS_MODULE #include <lisp.h> or better, we package up an <emacs.h> file the way Stefan suggested. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-09 0:04 ` Aurélien Aptel 2015-02-09 0:34 ` Paul Eggert @ 2015-02-10 14:56 ` Ted Zlatanov 2015-02-11 9:55 ` Aurélien Aptel 1 sibling, 1 reply; 765+ messages in thread From: Ted Zlatanov @ 2015-02-10 14:56 UTC (permalink / raw) To: emacs-devel On Mon, 9 Feb 2015 01:04:44 +0100 Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: AA> Ok, what I've pushed on my branch is now working. Thanks! I pushed today's version to the Emacs repo in branch feature/aptel/dynamic-modules-rc3 AA> One last thing, I need a deep `equal' function that also works AA> hash-tables (every key and values must be equal) in yaml/test.el to AA> compare nested lisp objects. Do I need to hand roll this myself? Your `yaml-equal' seems OK to me :) Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-10 14:56 ` Ted Zlatanov @ 2015-02-11 9:55 ` Aurélien Aptel 2015-02-11 16:05 ` Ted Zlatanov 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-02-11 9:55 UTC (permalink / raw) To: Emacs development discussions On Tue, Feb 10, 2015 at 3:56 PM, Ted Zlatanov <tzz@lifelogs.com> wrote: > Thanks! I pushed today's version to the Emacs repo in branch feature/aptel/dynamic-modules-rc3 Thanks Ted. I remember some people were already having build issues with rc2. Can you confirm you can build rc3 (and my last commit, while we're at it)? > Your `yaml-equal' seems OK to me :) I had some help from bpalmer on #emacs, I personally don't speak CL loop :) ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-11 9:55 ` Aurélien Aptel @ 2015-02-11 16:05 ` Ted Zlatanov 2015-02-11 16:24 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Ted Zlatanov @ 2015-02-11 16:05 UTC (permalink / raw) To: emacs-devel On Wed, 11 Feb 2015 10:55:19 +0100 Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: AA> On Tue, Feb 10, 2015 at 3:56 PM, Ted Zlatanov <tzz@lifelogs.com> wrote: >> Thanks! I pushed today's version to the Emacs repo in branch feature/aptel/dynamic-modules-rc3 AA> Thanks Ted. I remember some people were already having build issues AA> with rc2. Can you confirm you can build rc3 (and my last commit, while AA> we're at it)? I pushed your latest commit defining the module structure as well. I did "make bootstrap" but now get: Symbol's function definition is void: defun Can you explain how to test? I'm able to build the master branch, then switched to yours and did "make maintainer-clean; make bootstrap" but get that error. I didn't get this error when I tested your code last time, but it seems like something I'm not cleaning up. Sorry if this is a FAQ. I'd like to merge this as soon as possible, even if there are rough edges, so we can start finding them. I think if I test this and it's OK, we should coordinate the ChangeLogs and documentation as we clean things up. It may make sense to squash some of the trivial commits as well. Thanks for your great work. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-11 16:05 ` Ted Zlatanov @ 2015-02-11 16:24 ` Aurélien Aptel 2015-02-11 21:17 ` Ted Zlatanov 2015-02-13 21:29 ` Stephen Leake 0 siblings, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-02-11 16:24 UTC (permalink / raw) To: Emacs development discussions On Wed, Feb 11, 2015 at 5:05 PM, Ted Zlatanov <tzz@lifelogs.com> wrote: > I did "make bootstrap" but now get: > > Symbol's function definition is void: defun I have no idea what is causing that :| Sometimes I also get "Symbol is void: ^?" but it doesn't make the tests fail... > Can you explain how to test? I'm able to build the master branch, then Run ./modules/tests.py. It should work no matter the current working directory. > switched to yours and did "make maintainer-clean; make bootstrap" but > get that error. I didn't get this error when I tested your code last > time, but it seems like something I'm not cleaning up. Sorry if this is > a FAQ. I don't trust the nested polylingual spaghetti monster that is autoconf and usually run ./autogen.sh && ./configure --with-ltdl && make -kj8 after big changes just to make sure. I have a i7 CPU with 8 core at home so it's ok :) (now if I had a SSD...) > I'd like to merge this as soon as possible, even if there are rough > edges, so we can start finding them. I think if I test this and it's OK, > we should coordinate the ChangeLogs and documentation as we clean things > up. It may make sense to squash some of the trivial commits as well. Glad to hear it. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-11 16:24 ` Aurélien Aptel @ 2015-02-11 21:17 ` Ted Zlatanov 2015-02-12 0:22 ` Aurélien Aptel ` (2 more replies) 2015-02-13 21:29 ` Stephen Leake 1 sibling, 3 replies; 765+ messages in thread From: Ted Zlatanov @ 2015-02-11 21:17 UTC (permalink / raw) To: emacs-devel On Wed, 11 Feb 2015 17:24:51 +0100 Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: AA> On Wed, Feb 11, 2015 at 5:05 PM, Ted Zlatanov <tzz@lifelogs.com> wrote: >> I did "make bootstrap" but now get: >> >> Symbol's function definition is void: defun AA> I have no idea what is causing that :| I think it's because --with-ltdl is not the default. It should be, right? Modules are enabled by default? AA> ./autogen.sh && ./configure --with-ltdl && make -kj8 OK, so the problem is that my system (Ubuntu 14.10) has that library but it's not autodetected. What can I do to help you find the problem? AA> Run ./modules/tests.py. It should work no matter the current working directory. I got: % ./modules/tests.py [*] testing module yaml... [*] building module... gcc -ggdb3 -Wall -I../../src -I../../lib `pkg-config yaml-0.1 --cflags` -fPIC -c yaml.c gcc -shared `pkg-config yaml-0.1 --libs` -o yaml.so yaml.o ../../lib-src/make-docfile yaml.c > yaml.doc rm yaml.o [*] running test.el... Eager macro-expansion failure: (void-variable ) Running 5 tests (2015-02-11 16:13:26-0500) /home/tzz/source/emacs/emacs/src/emacs: symbol lookup error: /home/tzz/source/emacs/emacs/modules/yaml/yaml.so: undefined symbol: yaml_parser_initialize [!] yaml tests failed I have libyaml-dev installed, but `pkg-config yaml-0.1 --cflags` returns nothing. That may be expected--I don't see a yaml.pc anywhere. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-11 21:17 ` Ted Zlatanov @ 2015-02-12 0:22 ` Aurélien Aptel 2015-02-12 10:07 ` Stephen Leake 2015-02-12 10:51 ` Stephen Leake 2015-02-12 21:39 ` Aurélien Aptel 2 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-02-12 0:22 UTC (permalink / raw) To: Emacs development discussions On Wed, Feb 11, 2015 at 10:17 PM, Ted Zlatanov <tzz@lifelogs.com> wrote: > I think it's because --with-ltdl is not the default. It should be, > right? Modules are enabled by default? They used to but Eli or Stefan said it should be off by default as it's still experimental. > AA> ./autogen.sh && ./configure --with-ltdl && make -kj8 > > OK, so the problem is that my system (Ubuntu 14.10) has that library but > it's not autodetected. What can I do to help you find the problem? http://diobla.info/code/load-example/ Can you make this work? If you had to change the flags, which one did you use? As an alternative solution, we could bundle ltdl with emacs: http://www.gnu.org/software/libtool/manual/html_node/Distributing-libltdl.html > /home/tzz/source/emacs/emacs/src/emacs: symbol lookup error: /home/tzz/source/emacs/emacs/modules/yaml/yaml.so: undefined symbol: yaml_parser_initialize > [!] yaml tests failed > > I have libyaml-dev installed, but `pkg-config yaml-0.1 --cflags` returns > nothing. That may be expected--I don't see a yaml.pc anywhere. This has more to do with --libs but it doesn't matter: if a package doesn't exist pkg-config prints an error message. Again, maybe try to find the right flags to build a sample libyaml program? We can go from there. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-12 0:22 ` Aurélien Aptel @ 2015-02-12 10:07 ` Stephen Leake 0 siblings, 0 replies; 765+ messages in thread From: Stephen Leake @ 2015-02-12 10:07 UTC (permalink / raw) To: emacs-devel Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: > On Wed, Feb 11, 2015 at 10:17 PM, Ted Zlatanov <tzz@lifelogs.com> wrote: >> I think it's because --with-ltdl is not the default. It should be, >> right? Modules are enabled by default? > > They used to but Eli or Stefan said it should be off by default as > it's still experimental. Which means the build is broken for the no modules config; that has to be fixed before merging to master. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-11 21:17 ` Ted Zlatanov 2015-02-12 0:22 ` Aurélien Aptel @ 2015-02-12 10:51 ` Stephen Leake 2015-02-12 18:02 ` Stephen Leake 2015-02-12 20:09 ` Stephen Leake 2015-02-12 21:39 ` Aurélien Aptel 2 siblings, 2 replies; 765+ messages in thread From: Stephen Leake @ 2015-02-12 10:51 UTC (permalink / raw) To: emacs-devel Ted Zlatanov <tzz@lifelogs.com> writes: > On Wed, 11 Feb 2015 17:24:51 +0100 Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: > > AA> On Wed, Feb 11, 2015 at 5:05 PM, Ted Zlatanov <tzz@lifelogs.com> wrote: >>> I did "make bootstrap" but now get: >>> >>> Symbol's function definition is void: defun > > AA> I have no idea what is causing that :| > > I think it's because --with-ltdl is not the default. It should be, > right? Modules are enabled by default? -with-ltdl fixes the problem for me on Windows mingw64. More testing later. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-12 10:51 ` Stephen Leake @ 2015-02-12 18:02 ` Stephen Leake 2015-02-14 0:49 ` Davis Herring 2015-02-12 20:09 ` Stephen Leake 1 sibling, 1 reply; 765+ messages in thread From: Stephen Leake @ 2015-02-12 18:02 UTC (permalink / raw) To: emacs-devel Stephen Leake <stephen_leake@stephe-leake.org> writes: > Ted Zlatanov <tzz@lifelogs.com> writes: > >> On Wed, 11 Feb 2015 17:24:51 +0100 Aurélien Aptel >> <aurelien.aptel+emacs@gmail.com> wrote: >> >> AA> On Wed, Feb 11, 2015 at 5:05 PM, Ted Zlatanov <tzz@lifelogs.com> wrote: >>>> I did "make bootstrap" but now get: >>>> >>>> Symbol's function definition is void: defun >> >> AA> I have no idea what is causing that :| >> >> I think it's because --with-ltdl is not the default. It should be, >> right? Modules are enabled by default? > > -with-ltdl fixes the problem for me on Windows mingw64. More testing later. When I run tests.py, I get: $ ./tests.py File "./tests.py", line 47 print "" ^ SyntaxError: invalid syntax Mingw64 has python 3.3 I can also run this under Cygwin, which has python 2.7.8; it does not give that error. So I'm assuming this is a python 2/3 incompatibility; is there a simple way to accomodate both? -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-12 18:02 ` Stephen Leake @ 2015-02-14 0:49 ` Davis Herring 0 siblings, 0 replies; 765+ messages in thread From: Davis Herring @ 2015-02-14 0:49 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel > $ ./tests.py > File "./tests.py", line 47 > print "" > ^ > SyntaxError: invalid syntax [...] > So I'm assuming this is a python 2/3 incompatibility; is there a simple > way to accomodate both? print("") means the same thing in each. For more complicated cases, one can write "from __future__ import print_function" to make Python >=2.6 act like Python 3. Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-12 10:51 ` Stephen Leake 2015-02-12 18:02 ` Stephen Leake @ 2015-02-12 20:09 ` Stephen Leake 2015-02-12 20:34 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Stephen Leake @ 2015-02-12 20:09 UTC (permalink / raw) To: emacs-devel Stephen Leake <stephen_leake@stephe-leake.org> writes: > Ted Zlatanov <tzz@lifelogs.com> writes: > >> On Wed, 11 Feb 2015 17:24:51 +0100 Aurélien Aptel >> <aurelien.aptel+emacs@gmail.com> wrote: >> >> AA> On Wed, Feb 11, 2015 at 5:05 PM, Ted Zlatanov <tzz@lifelogs.com> wrote: >>>> I did "make bootstrap" but now get: >>>> >>>> Symbol's function definition is void: defun >> >> AA> I have no idea what is causing that :| >> >> I think it's because --with-ltdl is not the default. It should be, >> right? Modules are enabled by default? > > -with-ltdl fixes the problem for me on Windows mingw64. More testing later. I had to add to options to the 'gcc' line in modules/curl/Makefile: -std=c99 -I$(ROOT)/nt/inc Normally those would be added by configure. Perhaps they could be set via CFLAGS by the perl script when on mingw64? But then I get link errors: stephe@takver$ make gcc -shared `pkg-config libcurl --libs` -o curl.so curl.o curl.o: In function `Fcurl_make': C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:55: undefined reference to `__imp_curl_easy_init' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:56: undefined reference to `make_save_ptr' curl.o: In function `Fcurl_fetch_url': C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:67: undefined reference to `XSAVE_POINTER' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:69: undefined reference to `SSDATA' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:69: undefined reference to `__imp_curl_easy_setopt' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:70: undefined reference to `__imp_curl_easy_setopt' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:71: undefined reference to `__imp_curl_easy_setopt' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:72: undefined reference to `__imp_curl_easy_setopt' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:73: undefined reference to `__imp_curl_easy_perform' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:77: undefined reference to `__imp_curl_easy_strerror' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:78: undefined reference to `make_string' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:81: undefined reference to `builtin_lisp_symbol' curl.o: In function `Fcurl_content': C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:89: undefined reference to `XSAVE_POINTER' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:90: undefined reference to `make_string' curl.o: In function `Fcurl_free': C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:98: undefined reference to `XSAVE_POINTER' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:100: undefined reference to `__imp_curl_easy_cleanup' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:102: undefined reference to `builtin_lisp_symbol' curl.o: In function `init': C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:107: undefined reference to `__imp_curl_global_init' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:110: undefined reference to `intern' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:112: undefined reference to `defsubr' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:113: undefined reference to `defsubr' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:114: undefined reference to `defsubr' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:115: undefined reference to `defsubr' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:117: undefined reference to `builtin_lisp_symbol' C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:117: undefined reference to `Fprovide' collect2.exe: error: ld returned 1 exit status Makefile:9: recipe for target 'curl.so' failed make: *** [curl.so] Error 1 pkg-config libcurl --libs returns -L/mingw64/lib -lcurl -lwldap32 -lz -lws2_32 The "__imp_curl*" functions are provided by /msys64/mingw64/lib/libcurl.dll.a; I assume that's what matches '-lcurl'. So I don't understand those errors. The other symbols appear to be Emacs symbols? There was some discussion about a special flag for exporting those on Windows; is that '-Xlinker -E'? I guess that goes in src/Makefile somewhere? We also discussed creating an 'emacs.h' file to export those symbols individually; I can work on that after I get the brute-force approach working. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-12 20:09 ` Stephen Leake @ 2015-02-12 20:34 ` Eli Zaretskii 2015-02-12 21:51 ` Aurélien Aptel 2015-02-13 21:09 ` Stephen Leake 0 siblings, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-02-12 20:34 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel > From: Stephen Leake <stephen_leake@stephe-leake.org> > Date: Thu, 12 Feb 2015 14:09:53 -0600 > > I had to add to options to the 'gcc' line in modules/curl/Makefile: > > -std=c99 -I$(ROOT)/nt/inc Why do you need -std=c99? What happens if you don't use it? GCC defaults to -std=gnu99, which is a superset of c99, so I don't understand why you needed to insist on strict C99. I also don't like the -I$(ROOT)/nt/inc thing, it should only be needed for Emacs-specific system-level stuff. Why was it needed here? > Normally those would be added by configure. Perhaps they could be set > via CFLAGS by the perl script when on mingw64? Sorry, I don't understand: the Emacs configure script already adds that directory to the include path. So what's wrong? > But then I get link errors: > > stephe@takver$ make > gcc -shared `pkg-config libcurl --libs` -o curl.so curl.o > curl.o: In function `Fcurl_make': > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:55: undefined reference to `__imp_curl_easy_init' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:56: undefined reference to `make_save_ptr' > curl.o: In function `Fcurl_fetch_url': > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:67: undefined reference to `XSAVE_POINTER' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:69: undefined reference to `SSDATA' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:69: undefined reference to `__imp_curl_easy_setopt' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:70: undefined reference to `__imp_curl_easy_setopt' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:71: undefined reference to `__imp_curl_easy_setopt' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:72: undefined reference to `__imp_curl_easy_setopt' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:73: undefined reference to `__imp_curl_easy_perform' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:77: undefined reference to `__imp_curl_easy_strerror' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:78: undefined reference to `make_string' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:81: undefined reference to `builtin_lisp_symbol' > curl.o: In function `Fcurl_content': > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:89: undefined reference to `XSAVE_POINTER' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:90: undefined reference to `make_string' > curl.o: In function `Fcurl_free': > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:98: undefined reference to `XSAVE_POINTER' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:100: undefined reference to `__imp_curl_easy_cleanup' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:102: undefined reference to `builtin_lisp_symbol' > curl.o: In function `init': > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:107: undefined reference to `__imp_curl_global_init' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:110: undefined reference to `intern' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:112: undefined reference to `defsubr' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:113: undefined reference to `defsubr' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:114: undefined reference to `defsubr' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:115: undefined reference to `defsubr' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:117: undefined reference to `builtin_lisp_symbol' > C:\Projects\emacs\feature\aptel\dynamic-modules-rc3\modules\curl/curl.c:117: undefined reference to `Fprovide' > collect2.exe: error: ld returned 1 exit status > Makefile:9: recipe for target 'curl.so' failed > make: *** [curl.so] Error 1 > > pkg-config libcurl --libs returns -L/mingw64/lib -lcurl -lwldap32 -lz -lws2_32 > > The "__imp_curl*" functions are provided by > /msys64/mingw64/lib/libcurl.dll.a; I assume that's what matches > '-lcurl'. So I don't understand those errors. GNU ld is a one-pass linker, so the libraries should be after the object files. > The other symbols appear to be Emacs symbols? There was some discussion > about a special flag for exporting those on Windows; is that '-Xlinker > -E'? I guess that goes in src/Makefile somewhere? The unresolved externals that are defined by Emacs are expected: you need to link against an import library produced as part of building emacs.exe. Otherwise all this stuff will not work on Windows, because the Windows port of the linker must see the import library at link time. The flag to produce the import library should be something like this: -Wl,--out-implib=libemacs.dll.a Then you need to link the shared library against -lemacs. And the link command line should produce curl.dll, not curl.so. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-12 20:34 ` Eli Zaretskii @ 2015-02-12 21:51 ` Aurélien Aptel 2015-02-12 21:55 ` Aurélien Aptel ` (2 more replies) 2015-02-13 21:09 ` Stephen Leake 1 sibling, 3 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-02-12 21:51 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stephen Leake, Emacs development discussions On Thu, Feb 12, 2015 at 9:34 PM, Eli Zaretskii <eliz@gnu.org> wrote: > Sorry, I don't understand: the Emacs configure script already adds > that directory to the include path. So what's wrong? He's talking about the module Makefile, which is very basic and standalone (no includes or preprocessing). > The unresolved externals that are defined by Emacs are expected: you > need to link against an import library produced as part of building > emacs.exe. Otherwise all this stuff will not work on Windows, because > the Windows port of the linker must see the import library at link > time. > > The flag to produce the import library should be something like this: > > -Wl,--out-implib=libemacs.dll.a > > Then you need to link the shared library against -lemacs. The configure script adds this to Emacs LD flags when modules are enabled: -lltdl -Wl,--export-dynamic What does that do on Windows? I have very little experience in C programming on Windows, especially using the GNU toolchain. I want to make this work but this is unknown territory for me. Is there an up-to-date guide to setup a simple build environment (libs and all) for Emacs on Windows? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-12 21:51 ` Aurélien Aptel @ 2015-02-12 21:55 ` Aurélien Aptel 2015-02-13 8:29 ` Eli Zaretskii 2015-02-13 19:09 ` Stefan Monnier 2015-02-13 8:27 ` Eli Zaretskii 2015-02-13 21:11 ` Stephen Leake 2 siblings, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-02-12 21:55 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stephen Leake, Emacs development discussions On Thu, Feb 12, 2015 at 10:51 PM, Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: > I want to make this work but this is unknown territory for me. Is > there an up-to-date guide to setup a simple build environment (libs > and all) for Emacs on Windows? Or even better, using Wine? Guess I'm asking for too much but switching OS really is a PITA. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-12 21:55 ` Aurélien Aptel @ 2015-02-13 8:29 ` Eli Zaretskii 2015-02-13 19:09 ` Stefan Monnier 1 sibling, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-02-13 8:29 UTC (permalink / raw) To: Aurélien Aptel; +Cc: stephen_leake, emacs-devel > Date: Thu, 12 Feb 2015 22:55:25 +0100 > From: Aurélien Aptel <aurelien.aptel+emacs@gmail.com> > Cc: Stephen Leake <stephen_leake@stephe-leake.org>, > Emacs development discussions <emacs-devel@gnu.org> > > On Thu, Feb 12, 2015 at 10:51 PM, Aurélien Aptel > <aurelien.aptel+emacs@gmail.com> wrote: > > I want to make this work but this is unknown territory for me. Is > > there an up-to-date guide to setup a simple build environment (libs > > and all) for Emacs on Windows? > > Or even better, using Wine? Guess I'm asking for too much but > switching OS really is a PITA. I never used Wine, but up front I don't see why nt/INSTALL won't DTRT for that case as well. AFAIK, Wine is just a Windows emulator, and setting up for building Emacs certainly doesn't call for messing with the OS ;-) ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-12 21:55 ` Aurélien Aptel 2015-02-13 8:29 ` Eli Zaretskii @ 2015-02-13 19:09 ` Stefan Monnier 1 sibling, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2015-02-13 19:09 UTC (permalink / raw) To: Aurélien Aptel Cc: Eli Zaretskii, Stephen Leake, Emacs development discussions > Or even better, using Wine? Guess I'm asking for too much but > switching OS really is a PITA. FWIW, I have used Wine to *run* the w32 build of Emacs and it worked well enough (not for real use, but to reproduce a particular bug and come up with a fix). I would expect that Wine can indeed similarly be used to build the w32 version of Emacs. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-12 21:51 ` Aurélien Aptel 2015-02-12 21:55 ` Aurélien Aptel @ 2015-02-13 8:27 ` Eli Zaretskii 2015-02-13 21:11 ` Stephen Leake 2 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-02-13 8:27 UTC (permalink / raw) To: Aurélien Aptel; +Cc: stephen_leake, emacs-devel > Date: Thu, 12 Feb 2015 22:51:22 +0100 > From: Aurélien Aptel <aurelien.aptel+emacs@gmail.com> > Cc: Stephen Leake <stephen_leake@stephe-leake.org>, > Emacs development discussions <emacs-devel@gnu.org> > > On Thu, Feb 12, 2015 at 9:34 PM, Eli Zaretskii <eliz@gnu.org> wrote: > > Sorry, I don't understand: the Emacs configure script already adds > > that directory to the include path. So what's wrong? > > He's talking about the module Makefile, which is very basic and > standalone (no includes or preprocessing). I don't really understand what that means, but I hope you will be able to help him. > > The unresolved externals that are defined by Emacs are expected: you > > need to link against an import library produced as part of building > > emacs.exe. Otherwise all this stuff will not work on Windows, because > > the Windows port of the linker must see the import library at link > > time. > > > > The flag to produce the import library should be something like this: > > > > -Wl,--out-implib=libemacs.dll.a > > > > Then you need to link the shared library against -lemacs. > > The configure script adds this to Emacs LD flags when modules are enabled: > > -lltdl -Wl,--export-dynamic > > What does that do on Windows? Nothing useful in this case, AFAIK. Reverse dynamic linking doesn't work on Windows. On Windows, when you link a shared library, the linker must be presented with either all the dependency object files, or with their import libraries. That's because the linker records inside the shared library data about the dependent object files and their names. In this case, we need to provide this information about Emacs, since (AFAIU) the module has unresolved externals that need to be dynamically linked to the corresponding Emacs symbols. So we need either to link the module against emacs.exe, or against an import library generated when Emacs is built. The latter is accomplished by using the --out-implib= option to the linker. Btw, when using the -Wl,--out-implib=libemacs.dll.a switch on the link command line, we will be by default exporting _all_ the externally visible symbols. That doesn't sound right (think DSO), and is even a source of possible problems, since Emacs on Windows redirects quite a few C library functions to its own implementations, and also adds some C library functions unavailable in the MS runtime. Making them visible to modules might mean trouble for those modules, if they rely on the standard or different implementations of those functions. So we should really have the emacs.h header file with only the functions and variables we want to export, and on Windows we should mark those exported functions and variables with dllexport attribute, so that only they are exported. (It is possible that we should also use some visibility attributes on ELF platforms, for similar reasons.) One other potential issue is with passing file names to modules. Emacs on Windows pretends that file-name-coding-system is UTF-8, so using ENCODE_FILE will produce a UTF-8 encoded file name that Windows runtime cannot grok. Therefore, the glue code, either in Lisp or in C, between Emacs and the module will have to convert the file name to the current system codepage (because most libraries only support that on Windows). > Is there an up-to-date guide to setup a simple build environment > (libs and all) for Emacs on Windows? Yes, see nt/INSTALL. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-12 21:51 ` Aurélien Aptel 2015-02-12 21:55 ` Aurélien Aptel 2015-02-13 8:27 ` Eli Zaretskii @ 2015-02-13 21:11 ` Stephen Leake 2 siblings, 0 replies; 765+ messages in thread From: Stephen Leake @ 2015-02-13 21:11 UTC (permalink / raw) To: emacs-devel [-- Attachment #1: Type: text/plain, Size: 325 bytes --] Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: > I want to make this work but this is unknown territory for me. Is > there an up-to-date guide to setup a simple build environment (libs > and all) for Emacs on Windows? Attached are my notes on installing msys2/mingw64 and building emacs. -- -- Stephe [-- Attachment #2: install_emacs_msys2.text --] [-- Type: application/octet-stream, Size: 4601 bytes --] notes on installing Emacs from source on Windows 7 using MinGW64 64 or 32 bit via Msys2. Here we give sources for the various packages needed. We give directions to the download, rather than an exact URL, to make it easy to check for new versions. These instructions work on a new computer, with only 64 bit Windows 7 installed. Msys2 provides all of the tools required, and several of the packages. These instructions are derived from http://sourceforge.net/p/msys2/wiki/MSYS2%20installation/ There are more detailed instructions at http://sourceforge.net/p/msys2/tickets/32/?limit=10&page=1#216b For more help, consult the mailing list at https://lists.sourceforge.net/lists/listinfo/msys2-users 01. MSYS2 install - if you have a 64 bit machine: From http://sourceforge.net/p/msys2/wiki/MSYS2%20installation/ download the 64 bit installer run msys2-x86_64-20141113.exe install to the default install directory c:/msys64 - if you have a 32 bit machine, the 32 bit installer (also works on a 64 bit machine, but is unnecessarily slower) run msys2-i686-20141113.exe install to the default install directory c:/msys32 The rest of these instructions assume a 64 bit machine; modify the paths accordingly. The installer offers to "Run Msys 64/32bit now."; check that. That starts an msys shell. Later, to update safely: - exit all msys2 processes, start a new shell from Windows Explorer: c:\msys64\mingw64_shell.bat - In the msys shell: $ pacman -Sy # updates local package database from central repository $ pacman -S --needed \ automake diffutils make autoconf pkg-config tar texinfo \ mingw-w64-i686-gcc mingw-w64-i686-libpng mingw-w64-i686-libjpeg-turbo mingw-w64-i686-libtiff \ mingw-w64-i686-giflib mingw-w64-i686-xpm-nox mingw-w64-i686-gnutls mingw-w64-i686-libxml2 \ mingw-w64-i686-librsvg 02. gcc 64 bit toolchain install - in the mingw64 shell (started with c:\msys64\mingw64_shell.bat): $ pacman -S --needed \ automake diffutils make autoconf pkg-config tar texinfo \ mingw-w64-x86_64-gcc mingw-w64-x86_64-libpng mingw-w64-x86_64-libjpeg-turbo mingw-w64-x86_64-libtiff \ mingw-w64-x86_64-giflib mingw-w64-x86_64-xpm-nox mingw-w64-x86_64-gnutls mingw-w64-x86_64-libxml2 \ mingw-w64-x86_64-librsvg 02a. for debugging emacs: $ pacman -S gdb 03 install libtool msys only has an msys libtool package, not a mingw64 package download libtool-2.4.tar.xz from http://ftp.gnu.org in msys64: $ cd /usr/src $ tar xz libtool-2.4.tar.xz $ cd libtool-2.5 $ ./configure --prefix=/mingw64 $ make install 03a. build Emacs from source tarball download http://alpha.gnu.org/gnu/emacs/pretest/emacs-24.3.93.tar.xz $ mkdir /c/Projects $ cd /c/Projects $ tar xf emacs-24.3.93.tar.xz $ cd emacs-24.3.93 $ ./configure --build=i686-pc-mingw32 --prefix=/mingw64 --with-ltdl # explicit --build not needed in emacs 25 $ make 03b. build Emacs from source git repository we build out of tree, in case we want to also build with another compiler or options $ git clone ssh://<user>@git.sv.gnu.org/srv/git/emacs.git master $ cd master $ ./autogen.sh $ mkdir ../master-build-mingw64 $ cd ../master-build-mingw64 $ ../master/configure --with-ltdl $ make to configure with debug optimization: $ export CFLAGS="-g3 -gdwarf-2 -O0" ; ../master/configure useful git links: http://www.emacswiki.org/emacs/GitForEmacsDevs https://savannah.gnu.org/git/?group=emacs 03c. run modules tests pacman does not have mingw64 libcurl download curl-7.40.0.tar.bz2 from http://curl.haxx.se/download.html in msys64: $ cd /usr/src $ tar xf curl-7.40.0.tar.bz2 $ cd curl-7.40.0 $ ./configure --prefix=/mingw64 $ make install $ pacman -S python $ cd /c/Projects/emacs/master/modules $ ./tests.py 04. build Emacs docs this requires extra tools from cygwin (tex stuff not in msys2 yet): texinfo texinfo-tex texlive-collection-latexextra texlive-collection-latexrecommended texlive-collection-fontsrecommended However, Cygwin has texinfo 5, which is significantly slower than texinfo 4. Texinfo 4 is available at: https://sourceforge.net/projects/ezwinports/files/?source=navbar ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-12 20:34 ` Eli Zaretskii 2015-02-12 21:51 ` Aurélien Aptel @ 2015-02-13 21:09 ` Stephen Leake 2015-02-14 9:31 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Stephen Leake @ 2015-02-13 21:09 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Stephen Leake <stephen_leake@stephe-leake.org> >> Date: Thu, 12 Feb 2015 14:09:53 -0600 >> >> I had to add to options to the 'gcc' line in modules/curl/Makefile: >> >> -std=c99 -I$(ROOT)/nt/inc > > Why do you need -std=c99? What happens if you don't use it? It complains about the "register" keyword in string.h stpcpy >GCC > defaults to -std=gnu99, Apparently not in Mingw64 > I also don't like the -I$(ROOT)/nt/inc thing, it should only be needed > for Emacs-specific system-level stuff. Why was it needed here? some file included ms-w32.h: stephe@takver$ make gcc -std=c99 -ggdb3 -Wall -I../../src -I../../lib `pkg-config libcurl --cflags` -fPIC -c curl.c curl.c:1:0: warning: -fPIC ignored for target (all code is position independent) #include <stdio.h> ^ In file included from ../../src/config.h:1866:0, from curl.c:6: ../../src/conf_post.h:32:27: fatal error: ms-w32.h: No such file or directory >> Normally those would be added by configure. Perhaps they could be set >> via CFLAGS by the perl script when on mingw64? > > Sorry, I don't understand: the Emacs configure script already adds > that directory to the include path. So what's wrong? I'm not running the top level Emacs makefile; I'm running modules/curl/Makefile, in order to build the curl module. >> But then I get link errors: >> >> <snip> > > GNU ld is a one-pass linker, so the libraries should be after the > object files. Ah, right; I forgot about link order. That fixes the libcurl problem. But the original order worked on Debian. >> The other symbols appear to be Emacs symbols? There was some discussion >> about a special flag for exporting those on Windows; is that '-Xlinker >> -E'? I guess that goes in src/Makefile somewhere? > > The unresolved externals that are defined by Emacs are expected: you > need to link against an import library produced as part of building > emacs.exe. Right, but I was expecting this makefile to do that. Especially since it "just works" on Debian. > Otherwise all this stuff will not work on Windows, because > the Windows port of the linker must see the import library at link > time. Apparently that is not true on Debian. > The flag to produce the import library should be something like this: > > -Wl,--out-implib=libemacs.dll.a And that goes in src/Makefile somewhere? Not on the "emacs$(EXEEXT)" line, since that doesn't run gcc. So it must go on the temacs$(EXEEXT) line (line 693)? And until we write emacs.h, it also needs -Xlinker -E (or can that be -Wl,-E ?). That should be added by configure when Windows and --with-ltdl are specified. Hmm. We already have: LIBLTDL = -lltdl -Wl,--export-dynamic which is included in LIBES, and thus in the temacs.exe link. However, that produces a warning: C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/4.9.2/../../../../x86_64-w64-mingw32/bin/ld.exe: warning: --export-dynamic is not supported for PE+ targets, did you mean --export-all-symbols? So apparently that should be changed to --export-all-symbols? Doing that produces libemacs.dll.a "--export-dynamic" is currently set in ./configure.ac line 3266; that needs to be customized for the OS. Apparently the right way to do that is with something like: if test "${opsys}" = "mingw64" || test "${opsys}" = "mingw32"; then #FIXME: should export only symbols defined in emacs.h (which doesn't exist yet) LIBLTDL="-lltdl -Wl,--export-all-symbols -Wl,--out-implib=libemacs.dll.a" else LIBLTDL="-lltdl -Wl,--export-dynamic" fi > Then you need to link the shared library against -lemacs. > > And the link command line should produce curl.dll, not curl.so. Ok, that produced curl.dll. But doing: src/emacs.exe -L modules/curl & (require 'curl) fails, with "eval: Cannot open load file: No such file or directory, curl". That same test works on Debian. Hmm. There is no curl/test.el, so this is _not_ designed to be part of the test suite. Sigh. I'll work on the other module/* directories, which do have test.el files. So one question is how to make this Makefile do the right thing for the current operating system. The intent is for this Makefile to be part of the Emacs test suite, so it needs to not require user intervention. One option is to rename modules/curl/Makefile to modules/curl/Makefile.in and use configure in the modules directories. Another is to set flags in modules/tests.py. I would prefer the former, since that makes each Makefile self-documenting. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-13 21:09 ` Stephen Leake @ 2015-02-14 9:31 ` Eli Zaretskii 2015-02-14 15:13 ` Stephen Leake 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-14 9:31 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel > From: Stephen Leake <stephen_leake@stephe-leake.org> > Date: Fri, 13 Feb 2015 15:09:08 -0600 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> From: Stephen Leake <stephen_leake@stephe-leake.org> > >> Date: Thu, 12 Feb 2015 14:09:53 -0600 > >> > >> I had to add to options to the 'gcc' line in modules/curl/Makefile: > >> > >> -std=c99 -I$(ROOT)/nt/inc > > > > Why do you need -std=c99? What happens if you don't use it? > > It complains about the "register" keyword in string.h stpcpy > > >GCC > > defaults to -std=gnu99, > > Apparently not in Mingw64 I don't think this is true, as that is a general feature of GCC independent of the platform. But in any case, -std=c99 is rarely what you want, since it's a rare program that conforms to strict ANSI C99 spec. Use -std=gnu99 instead. > > I also don't like the -I$(ROOT)/nt/inc thing, it should only be needed > > for Emacs-specific system-level stuff. Why was it needed here? > > some file included ms-w32.h: > > stephe@takver$ make > gcc -std=c99 -ggdb3 -Wall -I../../src -I../../lib `pkg-config libcurl --cflags` -fPIC -c curl.c > curl.c:1:0: warning: -fPIC ignored for target (all code is position independent) > #include <stdio.h> > ^ > In file included from ../../src/config.h:1866:0, > from curl.c:6: > ../../src/conf_post.h:32:27: fatal error: ms-w32.h: No such file or directory This is wrong on several levels. First, the module shouldn't use "-fPIC" unconditionally, as on some platforms, such as Windows, it invokes a warning and is otherwise ignored. More importantly, it is dead wrong for modules to include headers in lib/, and in particular they should NEVER include Emacs's config.h. That's because a config.h produced for a program or library should never be used by another program or library -- it includes stuff specific to that program/library. On Windows, doing so will get you in trouble because ms-w32.h includes all kinds of tricks and function redirections/redefinitions that will most probably break any non-trivial code which interfaces with an external library. The above is an example of such trouble, and the "solution" of add -I../nt -s a wrong solution. So the question now becomes: what happens if you _remove_ the "-I../../lib" option from the GCC command line? If that doesn't work, then we really need an emacs.h file ASAP, and the module should include only that file, without including <config.h> inside that file. > >> Normally those would be added by configure. Perhaps they could be set > >> via CFLAGS by the perl script when on mingw64? > > > > Sorry, I don't understand: the Emacs configure script already adds > > that directory to the include path. So what's wrong? > > I'm not running the top level Emacs makefile; I'm running > modules/curl/Makefile, in order to build the curl module. > > > GNU ld is a one-pass linker, so the libraries should be after the > > object files. > > Ah, right; I forgot about link order. That fixes the libcurl problem. > But the original order worked on Debian. On Debian, you don't need to link against the import library, that's why. > >> The other symbols appear to be Emacs symbols? There was some discussion > >> about a special flag for exporting those on Windows; is that '-Xlinker > >> -E'? I guess that goes in src/Makefile somewhere? > > > > The unresolved externals that are defined by Emacs are expected: you > > need to link against an import library produced as part of building > > emacs.exe. > > Right, but I was expecting this makefile to do that. Especially since it > "just works" on Debian. > > > Otherwise all this stuff will not work on Windows, because > > the Windows port of the linker must see the import library at link > > time. > > Apparently that is not true on Debian. Yes, and I tried to explain why. Dynamic linking on Posix systems works differently: the reference to external symbols is left at zero, and is resolved at run time. On Windows, these references cannot be left unresolved, so using the import library allows the linker to resolve them to an "import symbol" which is just an indirect call through a dispatch table. > > The flag to produce the import library should be something like this: > > > > -Wl,--out-implib=libemacs.dll.a > > And that goes in src/Makefile somewhere? Not on the "emacs$(EXEEXT)" > line, since that doesn't run gcc. So it must go on the temacs$(EXEEXT) > line (line 693)? Yes, it should be part of the temacs link command. > And until we write emacs.h, it also needs -Xlinker -E (or can that > be -Wl,-E ?). I don't see what does a header file have to do with linking. Why do you think you need that option? > That should be added by configure when Windows and --with-ltdl are > specified. I'd imagine --with-modules, not --with-ltdl, but I didn't take a look at the branch yet. > Hmm. We already have: > > LIBLTDL = -lltdl -Wl,--export-dynamic > > which is included in LIBES, and thus in the temacs.exe link. However, > that produces a warning: > > C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/4.9.2/../../../../x86_64-w64-mingw32/bin/ld.exe: > warning: --export-dynamic is not supported for PE+ targets, did you mean > --export-all-symbols? > > So apparently that should be changed to --export-all-symbols? Doing that > produces libemacs.dll.a No, using --export-all-symbols is wrong. See my other message in this thread. We don't want to export all the Emacs symbols to the outside world. Please use -Wl,--out-implib= instead. > > Then you need to link the shared library against -lemacs. > > > > And the link command line should produce curl.dll, not curl.so. > > Ok, that produced curl.dll. But doing: > > src/emacs.exe -L modules/curl & > (require 'curl) > > fails, with "eval: Cannot open load file: No such file or directory, > curl". That most probably means the module support stuff doesn't tell Emacs where to find the library. Or maybe it tries to load curl.so or something. I really don't know, you should debug this. > That same test works on Debian. GNU/Linux is what Aurélien tested this on, so it shouldn't surprise you it works on GNU/Linux, but not on Windows. IOW, it's not an interesting data point. > So one question is how to make this Makefile do the right thing > for the current operating system. The intent is for this Makefile to be > part of the Emacs test suite, so it needs to not require user intervention. Indeed, this is part of the job of figuring out how to use modules in Emacs. Apparently, that part was not yet done. > One option is to rename modules/curl/Makefile to > modules/curl/Makefile.in and use configure in the modules directories. Which configure? the Emacs configure? That'd be a wrong solution, IMO, as it will require the Emacs maintainers to know about modules in order to DTRT for them in our mainline configure script. So if Autoconf should be used to generate Makefile's in the modules, it should be their own configure scripts. > Another is to set flags in modules/tests.py. That requires Python, which is an additional requirement for the build environment. I'd rather we used Emacs for that. Alternatively, if the number of different settings is small, we could assume GNU Make and use its conditional directives to cater to the few different platforms. That's much easier, but doesn't scale well to large and complex modules. But perhaps that's not a big deal, if we assume modules will not be large and complex. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 9:31 ` Eli Zaretskii @ 2015-02-14 15:13 ` Stephen Leake 2015-02-14 15:51 ` Eli Zaretskii 2015-02-15 18:39 ` Stefan Monnier 0 siblings, 2 replies; 765+ messages in thread From: Stephen Leake @ 2015-02-14 15:13 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> > I also don't like the -I$(ROOT)/nt/inc thing, it should only be needed >> > for Emacs-specific system-level stuff. Why was it needed here? >> >> some file included ms-w32.h: >> >> stephe@takver$ make >> gcc -std=c99 -ggdb3 -Wall -I../../src -I../../lib `pkg-config libcurl --cflags` -fPIC -c curl.c >> curl.c:1:0: warning: -fPIC ignored for target (all code is position independent) >> #include <stdio.h> >> ^ >> In file included from ../../src/config.h:1866:0, >> from curl.c:6: >> ../../src/conf_post.h:32:27: fatal error: ms-w32.h: No such file or directory > > This is wrong on several levels. First, the module shouldn't use > "-fPIC" unconditionally, as on some platforms, such as Windows, it > invokes a warning and is otherwise ignored. Right. More reason to use configure. > So the question now becomes: what happens if you _remove_ the > "-I../../lib" option from the GCC command line? gcc -std=gnu99 -ggdb3 -Wall -I../../src `pkg-config libcurl --cflags` -c curl.c In file included from curl.c:8:0: ../../src/lisp.h:32:22: fatal error: intprops.h: No such file or directory #include <intprops.h> ^ compilation terminated. intprops.h is in lib; that explains why -I../../lib is needed. > If that doesn't work, then we really need an emacs.h file ASAP, and > the module should include only that file, without including <config.h> > inside that file. Nor <lisp.h>. And probably not lots of other things. >> > -Wl,--out-implib=libemacs.dll.a >> >> And that goes in src/Makefile somewhere? Not on the "emacs$(EXEEXT)" >> line, since that doesn't run gcc. So it must go on the temacs$(EXEEXT) >> line (line 693)? > > Yes, it should be part of the temacs link command. > >> And until we write emacs.h, it also needs -Xlinker -E (or can that >> be -Wl,-E ?). > > I don't see what does a header file have to do with linking. -Wl,-E is short for -Wl,--export-all-symbols; that makes all symbols declared in Emacs visible to the module. (Similarly, --export-dynamic makes all symbols visible on Debian). I'm assuming emacs.h will include some annotation to make the symbols declared in that file visible, so we won't need --export-all-symbols (but more below). >> That should be added by configure when Windows and --with-ltdl are >> specified. > > I'd imagine --with-modules, not --with-ltdl, but I didn't take a look > at the branch yet. It's currently --with-ltdl, but I agree --with-modules is a better option name. >> Hmm. We already have: >> >> LIBLTDL = -lltdl -Wl,--export-dynamic >> >> which is included in LIBES, and thus in the temacs.exe link. However, >> that produces a warning: >> >> C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/4.9.2/../../../../x86_64-w64-mingw32/bin/ld.exe: >> warning: --export-dynamic is not supported for PE+ targets, did you mean >> --export-all-symbols? >> >> So apparently that should be changed to --export-all-symbols? Doing that >> produces libemacs.dll.a > > No, using --export-all-symbols is wrong. See my other message in this > thread. We don't want to export all the Emacs symbols to the outside > world. Please use -Wl,--out-implib= instead. How does that know which symbols to export? The help for Gnu ld --out-implib doesn't say. Testing; apparently it exports all symbols - emacs.dll.a did not change size. So --export-all-symbols is redundant, but I don't see how we are going to restrict what symbols are available to the module. Unless we are proposing to do that solely via .h files, not at the linker level. I think that's better - compile time errors are easier to understand than link time errors. We'll have to see how well that works. >> So one question is how to make this Makefile do the right thing >> for the current operating system. The intent is for this Makefile to be >> part of the Emacs test suite, so it needs to not require user intervention. > > Indeed, this is part of the job of figuring out how to use modules in > Emacs. Apparently, that part was not yet done. > >> One option is to rename modules/curl/Makefile to >> modules/curl/Makefile.in and use configure in the modules directories. > > Which configure? the Emacs configure? That'd be a wrong solution, > IMO, as it will require the Emacs maintainers to know about modules in > order to DTRT for them in our mainline configure script. Not modules in general, just the few that are in the Emacs test suite. > So if Autoconf should be used to generate Makefile's in the modules, > it should be their own configure scripts. That is true for normal modules, yes. >> Another is to set flags in modules/tests.py. > > That requires Python, which is an additional requirement for the build > environment. I'd rather we used Emacs for that. Ok. > Alternatively, if the number of different settings is small, we could > assume GNU Make and use its conditional directives to cater to the few > different platforms. That's much easier, but doesn't scale well to > large and complex modules. But perhaps that's not a big deal, if we > assume modules will not be large and complex. Is there an acceptable (ie portable and reliable) way to determine the OS in a Makefile? I'm not aware of one (short of Gnu config.guess). -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 15:13 ` Stephen Leake @ 2015-02-14 15:51 ` Eli Zaretskii 2015-02-15 1:04 ` Stephen Leake 2015-02-15 18:39 ` Stefan Monnier 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-14 15:51 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel > From: Stephen Leake <stephen_leake@stephe-leake.org> > Date: Sat, 14 Feb 2015 09:13:03 -0600 > > > So the question now becomes: what happens if you _remove_ the > > "-I../../lib" option from the GCC command line? > > gcc -std=gnu99 -ggdb3 -Wall -I../../src `pkg-config libcurl --cflags` -c curl.c > In file included from curl.c:8:0: > ../../src/lisp.h:32:22: fatal error: intprops.h: No such file or directory > #include <intprops.h> > ^ > compilation terminated. > > > intprops.h is in lib; that explains why -I../../lib is needed. No, it means including lisp.h without any changes will get you in trouble. > > If that doesn't work, then we really need an emacs.h file ASAP, and > > the module should include only that file, without including <config.h> > > inside that file. > > Nor <lisp.h>. And probably not lots of other things. None of the Emacs header files in src/ include config.h. But they might include other headers not appropriate for modules, like intprops.h above. This really is something that needs to be figured out and fixed before the modules are announced operational, at least on MS-Windows. > >> > -Wl,--out-implib=libemacs.dll.a > >> > >> And that goes in src/Makefile somewhere? Not on the "emacs$(EXEEXT)" > >> line, since that doesn't run gcc. So it must go on the temacs$(EXEEXT) > >> line (line 693)? > > > > Yes, it should be part of the temacs link command. > > > >> And until we write emacs.h, it also needs -Xlinker -E (or can that > >> be -Wl,-E ?). > > > > I don't see what does a header file have to do with linking. > > -Wl,-E is short for -Wl,--export-all-symbols; that makes all symbols > declared in Emacs visible to the module. (Similarly, --export-dynamic > makes all symbols visible on Debian). > > I'm assuming emacs.h will include some annotation to make the symbols > declared in that file visible, so we won't need --export-all-symbols > (but more below). As soon as some symbols are declared for export, -Wl,--out-implib= takes care to export only them, whereas -E will still export everything. > > No, using --export-all-symbols is wrong. See my other message in this > > thread. We don't want to export all the Emacs symbols to the outside > > world. Please use -Wl,--out-implib= instead. > > How does that know which symbols to export? The help for Gnu ld > --out-implib doesn't say. > > Testing; apparently it exports all symbols - emacs.dll.a did not change > size. So --export-all-symbols is redundant Yes, that's why I said --export-all-symbols should not be used. You don't need it. > but I don't see how we are going to restrict what symbols are > available to the module. The way to restrict the export is to declare the symbols you want to export with __declspec(dllexport). Then only those symbols will be exported. Note that, since emacs.h will be included by modules as well, we will need something like #ifdef WINDOWS # ifdef emacs # define EMACS_EXPORT __declspec(dllexport) # else # define EMACS_EXPORT __declspec(dllimport) # endif # else # define EMACS_EXPORT #endif That's because they should be exported by Emacs, but imported by modules. > Is there an acceptable (ie portable and reliable) way to determine the > OS in a Makefile? I'm not aware of one (short of Gnu config.guess). Windows can be detected by looking at environment variables. Since Make converts them to Make variables, they are easily accessed. Another possibility is to invoke "gcc -dumpmachine" via the $shell function. We could also invoke uname in a similar manner, but that requires MSYS or Coreutils to be installed. We could even invoke Make itself with the --version option, and see what follows the "Built for" header. So ways to do that exist, we just need to decide whether we want to go that way. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 15:51 ` Eli Zaretskii @ 2015-02-15 1:04 ` Stephen Leake 2015-02-15 13:50 ` Daniel Colascione 0 siblings, 1 reply; 765+ messages in thread From: Stephen Leake @ 2015-02-15 1:04 UTC (permalink / raw) To: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> but I don't see how we are going to restrict what symbols are >> available to the module. > > The way to restrict the export is to declare the symbols you want to > export with __declspec(dllexport). Then only those symbols will be > exported. > > Note that, since emacs.h will be included by modules as well, we will > need something like > > #ifdef WINDOWS > # ifdef emacs > # define EMACS_EXPORT __declspec(dllexport) > # else > # define EMACS_EXPORT __declspec(dllimport) > # endif > # else > # define EMACS_EXPORT > #endif > > That's because they should be exported by Emacs, but imported by > modules. Right, that makes sense. >> Is there an acceptable (ie portable and reliable) way to determine the >> OS in a Makefile? I'm not aware of one (short of Gnu config.guess). > > Windows can be detected by looking at environment variables. Since > Make converts them to Make variables, they are easily accessed. > > Another possibility is to invoke "gcc -dumpmachine" via the $shell > function. We could also invoke uname in a similar manner, but that > requires MSYS or Coreutils to be installed. We could even invoke Make > itself with the --version option, and see what follows the "Built for" > header. > > So ways to do that exist, we just need to decide whether we want to go > that way. I've attempted to take that approach for other projects, and it isn't very portable -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 1:04 ` Stephen Leake @ 2015-02-15 13:50 ` Daniel Colascione 2015-02-15 17:00 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-02-15 13:50 UTC (permalink / raw) To: Stephen Leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1784 bytes --] On 02/14/2015 05:04 PM, Stephen Leake wrote: > Eli Zaretskii <eliz@gnu.org> writes: > >>> but I don't see how we are going to restrict what symbols are >>> available to the module. >> >> The way to restrict the export is to declare the symbols you want to >> export with __declspec(dllexport). Then only those symbols will be >> exported. >> >> Note that, since emacs.h will be included by modules as well, we will >> need something like >> >> #ifdef WINDOWS >> # ifdef emacs >> # define EMACS_EXPORT __declspec(dllexport) >> # else >> # define EMACS_EXPORT __declspec(dllimport) >> # endif >> # else >> # define EMACS_EXPORT >> #endif >> >> That's because they should be exported by Emacs, but imported by >> modules. > > Right, that makes sense. No it doesn't. Modules shouldn't be importing anything from Emacs: Emacs should _give_ modules a table of all function pointers they need. It's a lot less error-prone that way. > >>> Is there an acceptable (ie portable and reliable) way to determine the >>> OS in a Makefile? I'm not aware of one (short of Gnu config.guess). >> >> Windows can be detected by looking at environment variables. Since >> Make converts them to Make variables, they are easily accessed. >> >> Another possibility is to invoke "gcc -dumpmachine" via the $shell >> function. We could also invoke uname in a similar manner, but that >> requires MSYS or Coreutils to be installed. We could even invoke Make >> itself with the --version option, and see what follows the "Built for" >> header. >> >> So ways to do that exist, we just need to decide whether we want to go >> that way. > > I've attempted to take that approach for other projects, and it isn't > very portable > [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 13:50 ` Daniel Colascione @ 2015-02-15 17:00 ` Eli Zaretskii 2015-02-15 17:04 ` Daniel Colascione 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-15 17:00 UTC (permalink / raw) To: Daniel Colascione; +Cc: stephen_leake, emacs-devel > Date: Sun, 15 Feb 2015 05:50:07 -0800 > From: Daniel Colascione <dancol@dancol.org> > > >> #ifdef WINDOWS > >> # ifdef emacs > >> # define EMACS_EXPORT __declspec(dllexport) > >> # else > >> # define EMACS_EXPORT __declspec(dllimport) > >> # endif > >> # else > >> # define EMACS_EXPORT > >> #endif > >> > >> That's because they should be exported by Emacs, but imported by > >> modules. > > > > Right, that makes sense. > > No it doesn't. Modules shouldn't be importing anything from Emacs: Emacs > should _give_ modules a table of all function pointers they need. It's a > lot less error-prone that way. I don't follow: how will the linker succeed in linking the module's shared library, if you don't submit to it an import library with the symbols in that table you mention? And how do you suggest to produce an import library, except by the above decorations? What am I missing? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 17:00 ` Eli Zaretskii @ 2015-02-15 17:04 ` Daniel Colascione 2015-02-15 17:28 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-02-15 17:04 UTC (permalink / raw) To: Eli Zaretskii; +Cc: stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1340 bytes --] On 02/15/2015 09:00 AM, Eli Zaretskii wrote: >> Date: Sun, 15 Feb 2015 05:50:07 -0800 >> From: Daniel Colascione <dancol@dancol.org> >> >>>> #ifdef WINDOWS >>>> # ifdef emacs >>>> # define EMACS_EXPORT __declspec(dllexport) >>>> # else >>>> # define EMACS_EXPORT __declspec(dllimport) >>>> # endif >>>> # else >>>> # define EMACS_EXPORT >>>> #endif >>>> >>>> That's because they should be exported by Emacs, but imported by >>>> modules. >>> >>> Right, that makes sense. >> >> No it doesn't. Modules shouldn't be importing anything from Emacs: Emacs >> should _give_ modules a table of all function pointers they need. It's a >> lot less error-prone that way. > > I don't follow: how will the linker succeed in linking the module's > shared library, if you don't submit to it an import library with the > symbols in that table you mention? And how do you suggest to produce > an import library, except by the above decorations? > > What am I missing? Emacs doesn't provide symbols to modules. Modules provide an initialization function to Emacs: Emacs then calls this initialization function with a pointer to a C structure containing a table of function pointers. Modules call these function pointers to do their work. There's no need for Emacs itself to export any symbols. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 17:04 ` Daniel Colascione @ 2015-02-15 17:28 ` Eli Zaretskii 2015-02-15 17:31 ` Daniel Colascione 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-15 17:28 UTC (permalink / raw) To: Daniel Colascione; +Cc: stephen_leake, emacs-devel > Date: Sun, 15 Feb 2015 09:04:01 -0800 > From: Daniel Colascione <dancol@dancol.org> > CC: stephen_leake@stephe-leake.org, emacs-devel@gnu.org > > Modules provide an initialization function to Emacs: Emacs then > calls this initialization function with a pointer to a C structure > containing a table of function pointers. Modules call these function > pointers to do their work. How will modules know which function in the table does what job? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 17:28 ` Eli Zaretskii @ 2015-02-15 17:31 ` Daniel Colascione 2015-02-15 18:00 ` Eli Zaretskii 2015-02-15 18:24 ` Andreas Schwab 0 siblings, 2 replies; 765+ messages in thread From: Daniel Colascione @ 2015-02-15 17:31 UTC (permalink / raw) To: Eli Zaretskii; +Cc: stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 763 bytes --] On 02/15/2015 09:28 AM, Eli Zaretskii wrote: >> Date: Sun, 15 Feb 2015 09:04:01 -0800 >> From: Daniel Colascione <dancol@dancol.org> >> CC: stephen_leake@stephe-leake.org, emacs-devel@gnu.org >> >> Modules provide an initialization function to Emacs: Emacs then >> calls this initialization function with a pointer to a C structure >> containing a table of function pointers. Modules call these function >> pointers to do their work. > > How will modules know which function in the table does what job? Positionally, as fixed in the structure that defines the table. struct { void (*func1)(int); void (*func2)(double); /* etc. */ } This way, the ABI Emacs exports is explicit, and breaking it is unlikely to happen accidentally. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 17:31 ` Daniel Colascione @ 2015-02-15 18:00 ` Eli Zaretskii 2015-02-15 18:01 ` Daniel Colascione 2015-02-15 18:24 ` Andreas Schwab 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-15 18:00 UTC (permalink / raw) To: Daniel Colascione; +Cc: stephen_leake, emacs-devel > Date: Sun, 15 Feb 2015 09:31:12 -0800 > From: Daniel Colascione <dancol@dancol.org> > CC: stephen_leake@stephe-leake.org, emacs-devel@gnu.org > > On 02/15/2015 09:28 AM, Eli Zaretskii wrote: > >> Date: Sun, 15 Feb 2015 09:04:01 -0800 > >> From: Daniel Colascione <dancol@dancol.org> > >> CC: stephen_leake@stephe-leake.org, emacs-devel@gnu.org > >> > >> Modules provide an initialization function to Emacs: Emacs then > >> calls this initialization function with a pointer to a C structure > >> containing a table of function pointers. Modules call these function > >> pointers to do their work. > > > > How will modules know which function in the table does what job? > > Positionally, as fixed in the structure that defines the table. > > struct { > void (*func1)(int); > void (*func2)(double); > /* etc. */ > } > > This way, the ABI Emacs exports is explicit, and breaking it is unlikely > to happen accidentally. I see. Would you like to propose a list of functions that should be in that table? I don't mean function names, I mean a short description of each one of them. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 18:00 ` Eli Zaretskii @ 2015-02-15 18:01 ` Daniel Colascione 2015-02-15 18:29 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-02-15 18:01 UTC (permalink / raw) To: Eli Zaretskii; +Cc: stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1438 bytes --] On 02/15/2015 10:00 AM, Eli Zaretskii wrote: >> Date: Sun, 15 Feb 2015 09:31:12 -0800 >> From: Daniel Colascione <dancol@dancol.org> >> CC: stephen_leake@stephe-leake.org, emacs-devel@gnu.org >> >> On 02/15/2015 09:28 AM, Eli Zaretskii wrote: >>>> Date: Sun, 15 Feb 2015 09:04:01 -0800 >>>> From: Daniel Colascione <dancol@dancol.org> >>>> CC: stephen_leake@stephe-leake.org, emacs-devel@gnu.org >>>> >>>> Modules provide an initialization function to Emacs: Emacs then >>>> calls this initialization function with a pointer to a C structure >>>> containing a table of function pointers. Modules call these function >>>> pointers to do their work. >>> >>> How will modules know which function in the table does what job? >> >> Positionally, as fixed in the structure that defines the table. >> >> struct { >> void (*func1)(int); >> void (*func2)(double); >> /* etc. */ >> } >> >> This way, the ABI Emacs exports is explicit, and breaking it is unlikely >> to happen accidentally. > > I see. > > Would you like to propose a list of functions that should be in that > table? I don't mean function names, I mean a short description of > each one of them. That depends on the supported module use cases, which are being discussed on other branches of the thread. Keep in mind that my first preference is still to do everything with CFFI and not export any Emacs-specific facilities at all. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 18:01 ` Daniel Colascione @ 2015-02-15 18:29 ` Eli Zaretskii 2015-02-15 20:20 ` Daniel Colascione 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-15 18:29 UTC (permalink / raw) To: Daniel Colascione; +Cc: stephen_leake, emacs-devel > Date: Sun, 15 Feb 2015 10:01:28 -0800 > From: Daniel Colascione <dancol@dancol.org> > CC: stephen_leake@stephe-leake.org, emacs-devel@gnu.org > > > Would you like to propose a list of functions that should be in that > > table? I don't mean function names, I mean a short description of > > each one of them. > > That depends on the supported module use cases, which are being > discussed on other branches of the thread. You can easily look at the modules already on the branch, I think they will give enough data points to at least start with this. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 18:29 ` Eli Zaretskii @ 2015-02-15 20:20 ` Daniel Colascione 2015-02-16 14:05 ` Aurélien Aptel ` (3 more replies) 0 siblings, 4 replies; 765+ messages in thread From: Daniel Colascione @ 2015-02-15 20:20 UTC (permalink / raw) To: Eli Zaretskii; +Cc: stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 12716 bytes --] On 02/15/2015 10:29 AM, Eli Zaretskii wrote: >> Date: Sun, 15 Feb 2015 10:01:28 -0800 >> From: Daniel Colascione <dancol@dancol.org> >> CC: stephen_leake@stephe-leake.org, emacs-devel@gnu.org >> >>> Would you like to propose a list of functions that should be in that >>> table? I don't mean function names, I mean a short description of >>> each one of them. >> >> That depends on the supported module use cases, which are being >> discussed on other branches of the thread. > > You can easily look at the modules already on the branch, I think they > will give enough data points to at least start with this. Here's a broad outline of what I have in mind. We want an ABI powerful enough to let C modules interact with Emacs, but decoupled enough to let the Emacs core evolve independently. The best model we have for an interface like that is JNI. See the specification at [1] for comparison. The JNI designers carefully considered issues like error propagation, GC integration, thread safety, type coercion, and so on, so let's depart from the JNI model only where there's a good reason to do so. We don't need all of JNI's complexity, but let's try to provide a simple subset with an option to extend it later. First, let's define a JNI-like entry point. Call it emacs_module_init: struct emacs_runtime; extern int emacs_module_init(struct emacs_runtime* ert); When Emacs loads a module, it uses dlsym (or the platform equivalent) to find this routine and call it. If it returns 0, the module loaded successfully; otherwise, we report an error to the caller. That's the limit of Emacs integration with the system dynamic loader. ERT provides functions the module can use to do everything else. We'll declare struct emacs_runtime ABI-stable; we can add fields to the end of the struct without breaking binary compatibility. Runtime environment ------------------- Let's define the emacs_runtime structure like this: struct emacs_runtime { size_t size; struct emacs_env (*get_environment)(struct emacs_runtime* ert); }; The `size' member tells modules how long the emacs_runtime structure is. (It's better to use size than an explicit version field: this way, .size = sizeof(struct emacs_runtime) is always correct.) Modules use `get_environment' to retrieve a pointer to an `emacs_env' structure that lets them do interesting things; Emacs also supplied module-registered callbacks with `emacs_env' pointers on entry. Thread-local environments ------------------------- The `get_environment' member lets us do anything else interesting. As in Java, environments are thread-local. We only support one thread for the moment, so this constraint is easy to enforce. (Just abort if we use an emacs_env off the main thread.) Now we can define emacs_env like this. (Ignore the forward definitions for the moment.) typedef struct emacs_env_25 emacs_env; typedef struct emacs_value_tag* emacs_value; typedef emacs_value (*emacs_subr)( emacs_env* env, int nargs, emacs_value args[]); struct emacs_env { size_t size /* struct size */; emacs_value (*make_global_reference)( emacs_env* env, emacs_value any_reference); void (*free_global_reference)( emacs_env* env, emacs_value global_reference); bool (*error_check)(emacs_env* env); void (*clear_error)(emacs_env* env); bool (*get_error)( emacs_env* env, emacs_value* error_symbol_out, emacs_value* error_data_out); void (*signal_error)( emacs_env* env, emacs_value error_symbol, emacs_value error_data); emacs_value (*make_function)( emacs_env* env, int min_arity, int max_arity, emacs_subr function); emacs_value (*funcall)( emacs_env* env, emacs_value function, int nargs, emacs_value args[]); emacs_value (*intern)( emacs_env* env, const char* symbol_name); emacs_value (*type_of)( emacs_env* env, emacs_value value); int64_t (*fixnum_to_int)( emacs_env* env, emacs_value value); emacs_value (*make_fixnum)( emacs_env* env, int64_t value); double (*float_to_c_double)( emacs_env* env, emacs_value value); emacs_value (*make_float)( emacs_env* env, double value); bool (*copy_string_contents)( emacs_env* env, emacs_value value, char* buffer, size_* length_inout); emacs_value (*make_string)( emacs_env* env, const char* contents); }; That's a pretty bare-boned interface. If we want, we can add more members for efficiency and functionality reasons. (Maybe car and cdr.) emacs_env size -------------- The first member in emacs_env is `size': that's just the size the emacs_env structure provided by emacs to a module. In emacs.h, we'd have something like this: struct emacs_env_25 { ... }; struct emacs_env_26 { ... }; ...; typedef struct emacs_env_26 emacs_env; This way, modules will use the latest version by default, but can check for a lesser version with something like this: if (env->size < sizeof(struct emacs_env_26)) { avoid_thing_that_works_only_in_emacs_26(); } Memory management ----------------- Let's steal from JNI some more. emacs_value (*make_global_reference)( emacs_env* env, emacs_value any_reference); void (*free_global_reference)( emacs_env* env, emacs_value global_reference); We'll represent all Lisp values as an opaque pointer typedef emacs_value. Each emacs_value is either a local or a global reference. Local references are valid only on the current thread and only while the module function Emacs called is on the stack --- think GCPRO. Global references are valid indefinitely: each one is a GC root. Modules can use make_global_reference to allocate a global reference (i.e., a GC root) for any emacs_value; modules must then free these references explicitly. All routines (except make_global_reference) that return emacs_value values return local references. It's up to modules to register long-lived references explicitly. This way, normal module code remains pretty efficient (since it deals only with stack-allocated local references), but can retain arbitrary data. Also, we don't lock ourselves into conservative stack-scanning GC. Error handling -------------- We can't longjmp through arbitrary C code! We have to let modules treat errors more conventionally. Let's use the JNI approach: bool (*error_check)(emacs_env* env); void (*clear_error)(emacs_env* env); bool (*get_error)( emacs_env* env, emacs_value* error_symbol_out, emacs_value* error_data_out); void (*signal_error)( emacs_env* env, emacs_value error_symbol, emacs_value error_data); We'll give each thread (initially, our only thread) a pending-error information. When Emacs calls a module function, the current thread's pending-error flag will be clear. When that module returns to Emacs, if the thread's pending-error flag is set, Emacs signals the condition corresponding to the current thread's error information. When the module calls an Emacs routine that would ordinarily signal, Emacs catches the signal at the stack frame just before control flow would return to the module, sets the pending-error flag, and returns to the module normally. (Functions that would return a value on success instead return a dummy value, like 0 or NULL.) `error_check' just returns true iff an error is pending. `clear_error' removes pending error information. `get_error' retrieves the pending error information, without clearing it, and returns true. If no error is set, it returns false. signal_error sets the current thread's pending-error flag. To simplify the interface, we can treat `catch' and 'throw' as special kinds of error. Like JNI, we can just declare that it's illegal to call all but a few specially-marked functions (like global reference deregistration) with a pending error. Function registration --------------------- typedef emacs_value (*emacs_subr)( emacs_env* env, int nargs, emacs_value args[]); emacs_value (*make_function)( emacs_env* env, int min_arity, int max_arity, emacs_subr function); emacs_value (*funcall)( emacs_env* env, emacs_value function, int nargs, emacs_value args[]); emacs_value (*intern)( emacs_env* env, const char* symbol_name); Modules create function values using make_function; it works like lambda; max_arity == -1 indicates a varargs function. Modules can register functions in the global namespace by calling a Lisp-level function; we can also just provide a `defun' API, although strictly speaking, one would be superfluous. When Lisp calls a module-defined function object, Emacs calls the emacs_subr callback with which the function was defined. Modules can call Lisp functions using `funcall', which does the obvious thing. If Lisp signals or throws, `funcall' returns NULL. `intern' also does the obvious thing. Type coercion ------------- emacs_value is not very useful without letting C look inside specific types of value. emacs_value (*type_of)( emacs_env* env, emacs_value value); Like Lisp type-of: returns a symbol. int64_t (*fixnum_to_int)( emacs_env* env, emacs_value value); emacs_value (*make_fixnum)( emacs_env* env, int64_t value); These functions do the obvious thing. They signal error on type mismatch. We use int64_t to handle big-integer Emacs variants on 32-bit platforms. double (*float_to_c_double)( emacs_env* env, emacs_value value); emacs_value (*make_float)( emacs_env* env, double value); These functions do the obvious thing. They signal on type mismatch. bool (*copy_string_contents)( emacs_env* env, emacs_value value, char* buffer, size_* length_inout); emacs_value (*make_string)( emacs_env* env, const char* contents); These functions let C code access Lisp strings. I imagine we'll always produce and consume UTF-8. `copy_string_contents' copies into a caller-allocated buffer instead of returning a char* callers must free() --- this way, modules and the Emacs core don't need to share the same C runtime. We can deal with the buffer-length issue in a number of ways: here, we just accept the destination buffer size in *length_inout and write the total length of the string to *length_inout on normal return. We just truncate if we're given too short a buffer and don't signal an error; this way, callers can loop around and allocate a sufficiently large buffer for a string's contents. Other functionality ------------------- I think the interface above is enough for complete functionality in a module, but for efficiency, we might want to expose additional facilities, like access to a unibyte buffer's raw representation. Convenience library --------------- This kind of interface is adequate, but asking callers to env->intern() every Emacs facility they want to use is inconvenient. It'd be nice to provide a statically-linked convenience library, written in terms of the ABI-stable interface, that made it straightforward to set text properties, visit files, and so on. For example, we could provide a function like this: bool emacs_find_file(emacs_env* env, const char* filename) { emacs_value e_filename = env->make_string(env, filename); if(env->error_check(env)) return false; emacs_value e_find_file = env->intern(env, "find-file"); if(env->error_check(env)) return false; return env->funcall(env, e_find_file, &e_filename, 1) != NULL; } Questions --------- 1) Do we need JNI-style local variable frames and functions that release local references? 2) Maybe we want a separate, non-emacs_value type for global references? 3) How exactly do we represent catch/throw values? 4) Do we need to use int64_t for integers? 5) Do we need to provide direct access to string contents? [1] http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html [2] Let's not support JNI's deprecated implicit registration system, where modules can register functions with the runtime by exporting symbols with certain magical names. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 20:20 ` Daniel Colascione @ 2015-02-16 14:05 ` Aurélien Aptel 2015-02-16 16:15 ` Eli Zaretskii 2015-02-16 15:43 ` Eli Zaretskii ` (2 subsequent siblings) 3 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-02-16 14:05 UTC (permalink / raw) To: Daniel Colascione Cc: Eli Zaretskii, Stephen Leake, Emacs development discussions On Sun, Feb 15, 2015 at 9:20 PM, Daniel Colascione <dancol@dancol.org> wrote: > 2) Maybe we want a separate, non-emacs_value type for global references? What for? > 4) Do we need to use int64_t for integers? It's probably simpler that way. > 5) Do we need to provide direct access to string contents? Strings are already stored as mostly UTF-8, why would you not provide direct access to that, at least read-only? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-16 14:05 ` Aurélien Aptel @ 2015-02-16 16:15 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-02-16 16:15 UTC (permalink / raw) To: Aurélien Aptel; +Cc: dancol, stephen_leake, emacs-devel > Date: Mon, 16 Feb 2015 15:05:49 +0100 > From: Aurélien Aptel <aurelien.aptel+emacs@gmail.com> > Cc: Eli Zaretskii <eliz@gnu.org>, Stephen Leake <stephen_leake@stephe-leake.org>, > Emacs development discussions <emacs-devel@gnu.org> > > > 5) Do we need to provide direct access to string contents? > > Strings are already stored as mostly UTF-8, why would you not provide > direct access to that, at least read-only? It's a superset of UTF-8, yes. However, the deviations are not insignificant, especially for unibyte strings. Dealing with their data requires knowledge that most people don't have (and don't need, IMO). ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 20:20 ` Daniel Colascione 2015-02-16 14:05 ` Aurélien Aptel @ 2015-02-16 15:43 ` Eli Zaretskii 2015-02-16 18:22 ` Daniel Colascione 2015-09-13 13:04 ` Philipp Stephani 2015-10-04 8:57 ` Philipp Stephani 3 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-16 15:43 UTC (permalink / raw) To: Daniel Colascione; +Cc: stephen_leake, emacs-devel > Date: Sun, 15 Feb 2015 12:20:35 -0800 > From: Daniel Colascione <dancol@dancol.org> > CC: stephen_leake@stephe-leake.org, emacs-devel@gnu.org > > Here's a broad outline of what I have in mind. Thanks. I think the next step is for someone to try rewriting a couple of modules on the branch in terms of this specification, and see if something is missing. Volunteers are welcome. Some comments on your write-up: > When Emacs loads a module, it uses dlsym (or the platform equivalent) > to find this routine and call it. If it returns 0, the module loaded > successfully; otherwise, we report an error to the caller. If this is all we need, then there's no need for libltdl, I think. > struct emacs_runtime { > size_t size; > struct emacs_env (*get_environment)(struct emacs_runtime* ert); > }; > > The `size' member tells modules how long the emacs_runtime structure > is. (It's better to use size than an explicit version field: this way, > .size = sizeof(struct emacs_runtime) is always correct.) This approach requires us to change the size each time we change the layout, even if the change itself leaves the size intact. Using a version field doesn't have this disadvantage. > Thread-local environments > ------------------------- > > The `get_environment' member lets us do anything else interesting. As > in Java, environments are thread-local. We only support one thread for > the moment, so this constraint is easy to enforce. (Just abort if we > use an emacs_env off the main thread.) Is it wise to design for threads at this point? The only suggestion on the table for "threads" is a far cry from real threads, and the current Lisp interpreter is otherwise thread-unsafe. Won't the thread infrastructure add a lot of cruft that will go unneeded for the observable future? > We'll represent all Lisp values as an opaque pointer typedef > emacs_value. Each emacs_value is either a local or a global > reference. Local references are valid only on the current thread and > only while the module function Emacs called is on the stack --- think > GCPRO. Global references are valid indefinitely: each one is a GC > root. With massive use of calls to Lisp functions from modules (since we don't provide them with direct access in C to internals of many objects), how can we ensure GC doesn't strike while the function that created an emacs_value is still on the callstack? You say "we don't lock ourselves into conservative stack-scanning GC", which I interpret as saying you don't want to rely on stack scanning to avoid a destructive GC in this case. But if we don't rely on that, where's the guarantee that such emacs_value will survive GC? > We'll represent all Lisp values as an opaque pointer typedef > emacs_value. This doesn't play well with --with-wide-int, where a value can be wider than a pointer. I think we should instead go with intmax_t or inptr_t, whichever is wider on the host. > Function registration > --------------------- > > typedef emacs_value (*emacs_subr)( > emacs_env* env, > int nargs, > emacs_value args[]); > > emacs_value (*make_function)( > emacs_env* env, > int min_arity, > int max_arity, > emacs_subr function); What about the doc string? > emacs_value (*funcall)( > emacs_env* env, > emacs_value function, > int nargs, > emacs_value args[]); Shouldn't funcall use emacs_subr? > Modules can register functions in the global namespace by calling a > Lisp-level function This is unclear, can you elaborate? What happens if a function is not "registered"? what's its status then? > When Lisp calls a module-defined function object, Emacs calls the > emacs_subr callback with which the function was defined. This is a change in the Lisp interpreter, I think. Why do we need this? > If Lisp signals or throws, `funcall' returns NULL. I suggest some other value or indication of that. NULL is a valid return value, so usurping it for errors might be too harsh. Or maybe I don't understand how will Lisp functions return values to the module, under your suggestion. Can you describe that? > `intern' also does the obvious thing. Do we need 'unintern' as well? > emacs_value (*type_of)( > emacs_env* env, > emacs_value value); > > Like Lisp type-of: returns a symbol. What is a "symbol", from the module's C code POV? You show no functions to access attributes of symbols, so it must be either one of the other types, like an integer or a string, or a C primitive data type, like a char * pointer. > int64_t (*fixnum_to_int)( > emacs_env* env, > emacs_value value); > > emacs_value (*make_fixnum)( > emacs_env* env, > int64_t value); > > These functions do the obvious thing. They signal error on type > mismatch. We use int64_t to handle big-integer Emacs variants on > 32-bit platforms. The last bit means we will need a utility function to return the valid range of integers, so that modules can be written to support 32-bit and 64-bit use cases without raising errors. > bool (*copy_string_contents)( > emacs_env* env, > emacs_value value, > char* buffer, > size_* length_inout); > > emacs_value (*make_string)( > emacs_env* env, > const char* contents); > > These functions let C code access Lisp strings. I imagine we'll > always produce and consume UTF-8. Strings in Emacs are of limited usability if you cannot encode and decode them. So this needs to be part of supported functionality, I think. More generally, modules that would like to process buffer or string text will have to be able to deal with Emacs's internal encoding of text, which means macros and functions we use in the core. The alternative of working only on UTF-8 encoded replica means we'd need to encode and decode text across the module boundaries -- that's a lot of consing. > `copy_string_contents' copies into a caller-allocated buffer instead > of returning a char* callers must free() --- this way, modules and the > Emacs core don't need to share the same C runtime. We can deal with > the buffer-length issue in a number of ways: here, we just accept the > destination buffer size in *length_inout and write the total length of > the string to *length_inout on normal return. We just truncate if > we're given too short a buffer and don't signal an error; this way, > callers can loop around and allocate a sufficiently large buffer for a > string's contents. That's an annoyance, IMO; why not provide a function to return the required size? Its implementation is trivial. > I think the interface above is enough for complete functionality in a > module, but for efficiency, we might want to expose additional > facilities, like access to a unibyte buffer's raw representation. I can envision a few additional missing bits: . direct access to buffer text (using buffer-substring means consing a lot of strings) . creation of opaque objects that should be returned to Lisp (like handles to objects managed by modules) . not sure how will a module "provide" its feature . some operations that must be efficient because they are typically done in inner loops, like regexp matching and accessing syntax of characters: doing that via Lisp will probably be horribly slow > Convenience library > --------------- One thing that's inconvenient is the need to drag the environment pointer through all the calls. Why exactly is that needed? > bool > emacs_find_file(emacs_env* env, const char* filename) > { > emacs_value e_filename = env->make_string(env, filename); > if(env->error_check(env)) return false; > emacs_value e_find_file = env->intern(env, "find-file"); > if(env->error_check(env)) return false; > return env->funcall(env, e_find_file, &e_filename, 1) != NULL; > } This kind of code looks tedious to me, no matter if it's in Emacs or in the module. Just an observation. Also, the buffer returned by find-file when it returns normally is lost here, isn't it? Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-16 15:43 ` Eli Zaretskii @ 2015-02-16 18:22 ` Daniel Colascione 2015-02-16 19:09 ` Stefan Monnier 2015-02-16 19:29 ` Eli Zaretskii 0 siblings, 2 replies; 765+ messages in thread From: Daniel Colascione @ 2015-02-16 18:22 UTC (permalink / raw) To: Eli Zaretskii; +Cc: stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 11687 bytes --] On 02/16/2015 07:43 AM, Eli Zaretskii wrote: >> Date: Sun, 15 Feb 2015 12:20:35 -0800 >> From: Daniel Colascione <dancol@dancol.org> >> CC: stephen_leake@stephe-leake.org, emacs-devel@gnu.org >> >> Here's a broad outline of what I have in mind. > > Thanks. I think the next step is for someone to try rewriting a > couple of modules on the branch in terms of this specification, and > see if something is missing. Volunteers are welcome. > > Some comments on your write-up: > >> When Emacs loads a module, it uses dlsym (or the platform equivalent) >> to find this routine and call it. If it returns 0, the module loaded >> successfully; otherwise, we report an error to the caller. > > If this is all we need, then there's no need for libltdl, I think. > >> struct emacs_runtime { >> size_t size; >> struct emacs_env (*get_environment)(struct emacs_runtime* ert); >> }; >> >> The `size' member tells modules how long the emacs_runtime structure >> is. (It's better to use size than an explicit version field: this way, >> .size = sizeof(struct emacs_runtime) is always correct.) > > This approach requires us to change the size each time we change the > layout, even if the change itself leaves the size intact. Using a > version field doesn't have this disadvantage. Emacs is allowed to pass a new version of the runtime and context structures to modules expecting old versions. That can only work if the structures are append-only, so `size' is adequate here. >> Thread-local environments >> ------------------------- >> >> The `get_environment' member lets us do anything else interesting. As >> in Java, environments are thread-local. We only support one thread for >> the moment, so this constraint is easy to enforce. (Just abort if we >> use an emacs_env off the main thread.) > > Is it wise to design for threads at this point? The only suggestion > on the table for "threads" is a far cry from real threads, and the > current Lisp interpreter is otherwise thread-unsafe. Won't the thread > infrastructure add a lot of cruft that will go unneeded for the > observable future? If it were a lot of cruft, I might agree with you, but it's not, so I'd rather make the design future-proof. >> We'll represent all Lisp values as an opaque pointer typedef >> emacs_value. Each emacs_value is either a local or a global >> reference. Local references are valid only on the current thread and >> only while the module function Emacs called is on the stack --- think >> GCPRO. Global references are valid indefinitely: each one is a GC >> root. > > With massive use of calls to Lisp functions from modules (since we > don't provide them with direct access in C to internals of many > objects), how can we ensure GC doesn't strike while the function that > created an emacs_value is still on the callstack? We don't. Calls from modules to Lisp can certainly GC. That's why we have local references. > You say "we don't > lock ourselves into conservative stack-scanning GC", which I interpret > as saying you don't want to rely on stack scanning to avoid a > destructive GC in this case. But if we don't rely on that, where's > the guarantee that such emacs_value will survive GC? Emacs stores emacs_value values in a local reference table before handing them to module code. >> We'll represent all Lisp values as an opaque pointer typedef >> emacs_value. > > This doesn't play well with --with-wide-int, where a value can be > wider than a pointer. I think we should instead go with intmax_t or > inptr_t, whichever is wider on the host. emacs_value objects are not literally Lisp_Object values. They're indirected through a reference table (either local or global) so that we can GC them. A pointer value can address all possible memory locations, so it's fine here. (In the wide-int case, the pointed-to table entries are wider than pointers, but modules don't need to know that.) >> Function registration >> --------------------- >> >> typedef emacs_value (*emacs_subr)( >> emacs_env* env, >> int nargs, >> emacs_value args[]); >> >> emacs_value (*make_function)( >> emacs_env* env, >> int min_arity, >> int max_arity, >> emacs_subr function); > > What about the doc string? We'll set that at the lisp level. make_function is equivalent to lambda, not defun. We can either let modules call `defun' directly or provide a special Lisp-level function just for them. >> emacs_value (*funcall)( >> emacs_env* env, >> emacs_value function, >> int nargs, >> emacs_value args[]); > > Shouldn't funcall use emacs_subr? Why? It works like Lisp funcall: you can give it a function object, a symbol, or a lambda expression. Remember that this facility lets an Emacs module call Lisp, not the other way around. >> Modules can register functions in the global namespace by calling a >> Lisp-level function > > This is unclear, can you elaborate? What happens if a function is not > "registered"? what's its status then? It has the same status a Lisp function does after defun. >> When Lisp calls a module-defined function object, Emacs calls the >> emacs_subr callback with which the function was defined. > > This is a change in the Lisp interpreter, I think. Why do we need > this? Why would it be? Implementation-wise, all we need is an Emacs-internal magic function for calling into modules; we can implement module-registered functions as Lisp-level lambdas that close over all the stuff we need to invoke the module code. >> If Lisp signals or throws, `funcall' returns NULL. > > I suggest some other value or indication of that. NULL is a valid > return value, so usurping it for errors might be too harsh. No it isn't. Qnil is distinct from NULL in this model because emacs_value is not a Lisp_Object in disguise. Qnil is not special here. > Or maybe I don't understand how will Lisp functions return values to > the module, under your suggestion. Can you describe that? > >> `intern' also does the obvious thing. > > Do we need 'unintern' as well? Modules can call unintern through Lisp. >> emacs_value (*type_of)( >> emacs_env* env, >> emacs_value value); >> >> Like Lisp type-of: returns a symbol. > > What is a "symbol", from the module's C code POV? It's an emacs_value. You can compare symbols (by calling `eq'), call them as functions, or use them as function arguments. That's sufficient. Come to think of it, though, we do need a C-level `eq'. > You show no > functions to access attributes of symbols, so it must be either one of > the other types, like an integer or a string, or a C primitive data > type, like a char * pointer. That's deliberate. Modules should be calling Lisp functions to do that work. >> int64_t (*fixnum_to_int)( >> emacs_env* env, >> emacs_value value); >> >> emacs_value (*make_fixnum)( >> emacs_env* env, >> int64_t value); >> >> These functions do the obvious thing. They signal error on type >> mismatch. We use int64_t to handle big-integer Emacs variants on >> 32-bit platforms. > > The last bit means we will need a utility function to return the valid > range of integers, so that modules can be written to support 32-bit > and 64-bit use cases without raising errors. Modules can call (get 'most-positive-fixnum). A utility function that did that wouldn't hurt though. >> bool (*copy_string_contents)( >> emacs_env* env, >> emacs_value value, >> char* buffer, >> size_* length_inout); >> >> emacs_value (*make_string)( >> emacs_env* env, >> const char* contents); >> >> These functions let C code access Lisp strings. I imagine we'll >> always produce and consume UTF-8. > > Strings in Emacs are of limited usability if you cannot encode and > decode them. So this needs to be part of supported functionality, I > think. > > More generally, modules that would like to process buffer or string > text will have to be able to deal with Emacs's internal encoding of > text, which means macros and functions we use in the core. The > alternative of working only on UTF-8 encoded replica means we'd need > to encode and decode text across the module boundaries -- that's a lot > of consing. Is the Emacs internal encoding stable? I don't have a problem with allowing modules to access string contents: it just enlarges the interface we'll have to support forever. Is consing strings really a bottleneck in the use cases we have in mind? >> `copy_string_contents' copies into a caller-allocated buffer instead >> of returning a char* callers must free() --- this way, modules and the >> Emacs core don't need to share the same C runtime. We can deal with >> the buffer-length issue in a number of ways: here, we just accept the >> destination buffer size in *length_inout and write the total length of >> the string to *length_inout on normal return. We just truncate if >> we're given too short a buffer and don't signal an error; this way, >> callers can loop around and allocate a sufficiently large buffer for a >> string's contents. > > That's an annoyance, IMO; why not provide a function to return the > required size? Its implementation is trivial. Sure --- as part of the non-ABI convenience library. >> I think the interface above is enough for complete functionality in a >> module, but for efficiency, we might want to expose additional >> facilities, like access to a unibyte buffer's raw representation. > > I can envision a few additional missing bits: > > . direct access to buffer text (using buffer-substring means consing > a lot of strings) Is that really a problem for the use cases we want to support? > . creation of opaque objects that should be returned to Lisp (like > handles to objects managed by modules) Sure. That'll require a new vectorlike. > . not sure how will a module "provide" its feature It doesn't. You don't require a module: you load it. Most modules will come with a small Lisp wrapper, just like Python modules. > . some operations that must be efficient because they are typically > done in inner loops, like regexp matching and accessing syntax of > characters: doing that via Lisp will probably be horribly slow That seems reasonable. >> Convenience library >> --------------- > > One thing that's inconvenient is the need to drag the environment > pointer through all the calls. Why exactly is that needed? Modules have no other way of accessing Emacs internals. Dragging one parameter through the system isn't that bad and lets us sanely track which module is doing what. >> bool >> emacs_find_file(emacs_env* env, const char* filename) >> { >> emacs_value e_filename = env->make_string(env, filename); >> if(env->error_check(env)) return false; >> emacs_value e_find_file = env->intern(env, "find-file"); >> if(env->error_check(env)) return false; >> return env->funcall(env, e_find_file, &e_filename, 1) != NULL; >> } > > This kind of code looks tedious to me, no matter if it's in Emacs or > in the module. Just an observation. We need explicit error handling. Within Emacs, we can use longjmp for error handling. In modules, we can't. > Also, the buffer returned by find-file when it returns normally is > lost here, isn't it? Sure. It's just a tiny example, and the returned buffer itself is still GCed. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-16 18:22 ` Daniel Colascione @ 2015-02-16 19:09 ` Stefan Monnier 2015-02-16 19:29 ` Eli Zaretskii 1 sibling, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2015-02-16 19:09 UTC (permalink / raw) To: Daniel Colascione; +Cc: Eli Zaretskii, stephen_leake, emacs-devel >> You say "we don't lock ourselves into conservative stack-scanning >> GC", which I interpret as saying you don't want to rely on stack >> scanning to avoid a destructive GC in this case. But if we don't >> rely on that, where's the guarantee that such emacs_value will >> survive GC? > Emacs stores emacs_value values in a local reference table before > handing them to module code. I don't think this is worth the trouble. I'm perfectly OK to either require stack scanning or to require modules use the same GCPRO macros we use in core. If/when we get a new GC technology that is incompatible with our GCPROs and/or stack scanning, well, then modules will break, but so will the rest of the Emacs core code so it's only fair. Stefan "who didn't read the rest of this thread, sorry" ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-16 18:22 ` Daniel Colascione 2015-02-16 19:09 ` Stefan Monnier @ 2015-02-16 19:29 ` Eli Zaretskii 2015-02-16 20:01 ` Daniel Colascione 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-16 19:29 UTC (permalink / raw) To: Daniel Colascione; +Cc: stephen_leake, emacs-devel > Date: Mon, 16 Feb 2015 10:22:18 -0800 > From: Daniel Colascione <dancol@dancol.org> > CC: stephen_leake@stephe-leake.org, emacs-devel@gnu.org > > >> The `size' member tells modules how long the emacs_runtime structure > >> is. (It's better to use size than an explicit version field: this way, > >> .size = sizeof(struct emacs_runtime) is always correct.) > > > > This approach requires us to change the size each time we change the > > layout, even if the change itself leaves the size intact. Using a > > version field doesn't have this disadvantage. > > Emacs is allowed to pass a new version of the runtime and context > structures to modules expecting old versions. That can only work if the > structures are append-only, so `size' is adequate here. I understand that, but appending members does not necessarily increase the size of the struct, due to alignment, bit fields, etc. > > You say "we don't > > lock ourselves into conservative stack-scanning GC", which I interpret > > as saying you don't want to rely on stack scanning to avoid a > > destructive GC in this case. But if we don't rely on that, where's > > the guarantee that such emacs_value will survive GC? > > Emacs stores emacs_value values in a local reference table before > handing them to module code. That's something that wasn't in your original writeup. Sounds like a significant part of the design. > >> We'll represent all Lisp values as an opaque pointer typedef > >> emacs_value. > > > > This doesn't play well with --with-wide-int, where a value can be > > wider than a pointer. I think we should instead go with intmax_t or > > inptr_t, whichever is wider on the host. > > emacs_value objects are not literally Lisp_Object values. They're > indirected through a reference table (either local or global) so that we > can GC them. A pointer value can address all possible memory locations, > so it's fine here. (In the wide-int case, the pointed-to table entries > are wider than pointers, but modules don't need to know that.) How this will work when some Lisp calls a primitive implemented by a module. From the Lisp interpreter POV, it's just a call to a primitive, so how will this special handling come into existence? (And why? just to save us from picking up a wider data type?) > > What about the doc string? > > We'll set that at the lisp level. I'm not following: what Lisp level? What I had in mind was a module that implements a primitive. Are you saying that every primitive a module wants to implement will need a Lisp part and a C part? That sounds cumbersome, just to save us from passing yet another argument to make_function. > >> emacs_value (*funcall)( > >> emacs_env* env, > >> emacs_value function, > >> int nargs, > >> emacs_value args[]); > > > > Shouldn't funcall use emacs_subr? > > Why? Because otherwise I see no point in having emacs_subr, it's almost unused. > >> If Lisp signals or throws, `funcall' returns NULL. > > > > I suggest some other value or indication of that. NULL is a valid > > return value, so usurping it for errors might be too harsh. > > No it isn't. Qnil is distinct from NULL in this model because > emacs_value is not a Lisp_Object in disguise. Qnil is not special here. I wasn't thinking about Qnil. I simply don't see why it is a good idea to forbid funcall from returning NULL in a normal case. > >> `intern' also does the obvious thing. > > > > Do we need 'unintern' as well? > > Modules can call unintern through Lisp. Then why provide 'intern'? It, too, can be called from Lisp. > >> emacs_value (*type_of)( > >> emacs_env* env, > >> emacs_value value); > >> > >> Like Lisp type-of: returns a symbol. > > > > What is a "symbol", from the module's C code POV? > > It's an emacs_value. You can compare symbols (by calling `eq'), call > them as functions, or use them as function arguments. That's sufficient. > > Come to think of it, though, we do need a C-level `eq'. Why not simply return a C enumeration type? > Is the Emacs internal encoding stable? It didn't change since Emacs 23, AFAIK. But working with the internal representation is not my idea of fun. > Is consing strings really a bottleneck in the use cases we have in > mind? I think we have no idea at this point which use cases we have in mind. > > . direct access to buffer text (using buffer-substring means consing > > a lot of strings) > > Is that really a problem for the use cases we want to support? It could be a problem for a module that processes buffer text. > > . not sure how will a module "provide" its feature > > It doesn't. You don't require a module: you load it. Most modules will > come with a small Lisp wrapper, just like Python modules. So do we _require_ a Lisp wrapper? Otherwise, how would Emacs know whether the module is loaded or not? > > One thing that's inconvenient is the need to drag the environment > > pointer through all the calls. Why exactly is that needed? > > Modules have no other way of accessing Emacs internals. Dragging one > parameter through the system isn't that bad and lets us sanely track > which module is doing what. The environment must be known to the module, that's for sure. But why does it have to be plugged into every call to every interface function? > > Also, the buffer returned by find-file when it returns normally is > > lost here, isn't it? > > Sure. It's just a tiny example, and the returned buffer itself is still > GCed. That's not what bothered me. I don't understand how will the module receive that return value in the first place. An additional argument to funcall, perhaps? Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-16 19:29 ` Eli Zaretskii @ 2015-02-16 20:01 ` Daniel Colascione 2015-02-17 15:43 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-02-16 20:01 UTC (permalink / raw) To: Eli Zaretskii; +Cc: stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 9940 bytes --] On 02/16/2015 11:29 AM, Eli Zaretskii wrote: >> Date: Mon, 16 Feb 2015 10:22:18 -0800 >> From: Daniel Colascione <dancol@dancol.org> >> CC: stephen_leake@stephe-leake.org, emacs-devel@gnu.org >> >>>> The `size' member tells modules how long the emacs_runtime structure >>>> is. (It's better to use size than an explicit version field: this way, >>>> .size = sizeof(struct emacs_runtime) is always correct.) >>> >>> This approach requires us to change the size each time we change the >>> layout, even if the change itself leaves the size intact. Using a >>> version field doesn't have this disadvantage. >> >> Emacs is allowed to pass a new version of the runtime and context >> structures to modules expecting old versions. That can only work if the >> structures are append-only, so `size' is adequate here. > > I understand that, but appending members does not necessarily increase > the size of the struct, due to alignment, bit fields, etc. If it's just a table of function pointers and everything has natural alignment, adding members will increase the size. >>> You say "we don't >>> lock ourselves into conservative stack-scanning GC", which I interpret >>> as saying you don't want to rely on stack scanning to avoid a >>> destructive GC in this case. But if we don't rely on that, where's >>> the guarantee that such emacs_value will survive GC? >> >> Emacs stores emacs_value values in a local reference table before >> handing them to module code. > > That's something that wasn't in your original writeup. Sounds like a > significant part of the design. I thought I'd made that clear. I'm glad I've been able to clarify it. Stefan doesn't seem to think the indirection is necessary, but I'm not sure I agree with him, especially because his scheme has a space and speed cost on 32-bit platforms. >>>> We'll represent all Lisp values as an opaque pointer typedef >>>> emacs_value. >>> >>> This doesn't play well with --with-wide-int, where a value can be >>> wider than a pointer. I think we should instead go with intmax_t or >>> inptr_t, whichever is wider on the host. >> >> emacs_value objects are not literally Lisp_Object values. They're >> indirected through a reference table (either local or global) so that we >> can GC them. A pointer value can address all possible memory locations, >> so it's fine here. (In the wide-int case, the pointed-to table entries >> are wider than pointers, but modules don't need to know that.) > > How this will work when some Lisp calls a primitive implemented by a > module. From the Lisp interpreter POV, it's just a call to a > primitive, so how will this special handling come into existence? > (And why? just to save us from picking up a wider data type?) I think there's some confusion about how function calls work. From the Lisp interpreter perspective, we're calling a regular Lisp function. That Lisp function closes over the information needed to call a module function and then calls into an Emacs core function that actually makes the module call. Say a module wants to provide a function "frobricate" taking two arguments. It defines a C-level function (call it do_frobricate) with a signature matching emacs_subr. It then calls `make_function' like this: emacs_value frobricate = env->make_function(env, 2, 2, do_frobricate) if (frobricate == NULL) { FAILURE(); } Now `frobricate' is a Lisp value usable in Lisp funcall; if we bind this value to the function slot of some symbol, Lisp code can call frobricate like any other function. Say do_frobricate has address 0xA3B41234. Implementation-wise, the value `frobricate` that `make_function' returned is a Lisp closure that essentially looks like this: (lambda (&rest args) (%do-module-call frobricate-module 0xA3B41234 2 2 args)) %do-module-call then clears the pending-error information, packs its arguments into a C array, and calls 0xA3B41234 like this: emacs_subr module_function = (module_function) 0xA3B41234; result = module_function(some_env, args, nargs); (I've left out the part where we transform emacs_value to Lisp_Object and vice versa.) >>> What about the doc string? >> >> We'll set that at the lisp level. > > I'm not following: what Lisp level? What I had in mind was a module > that implements a primitive. Are you saying that every primitive a > module wants to implement will need a Lisp part and a C part? That > sounds cumbersome, just to save us from passing yet another argument > to make_function. No: that's silly. I'm saying that creating a globally-named function in Emacs has two parts: 1) create the actual _function object_. 2) bind that function object to a name by setting some symbol's function slot to that function object. We can do step #2 entirely in Lisp code that the module calls, and we can set a documentation property at this time. It's only step #1 that requires a magical incantation. I've only described the magical, ABI-relevant bits of the interface. In order to make a module actually usable, we'll need glue, but since we can implement this glue in Lisp and call it from module code using the narrow interface I've described here, I'm not worried about it. >>>> emacs_value (*funcall)( >>>> emacs_env* env, >>>> emacs_value function, >>>> int nargs, >>>> emacs_value args[]); >>> >>> Shouldn't funcall use emacs_subr? >> >> Why? > > Because otherwise I see no point in having emacs_subr, it's almost > unused. emacs_subr is a typedef for a pointer to a module-provided function. Every module-provided function is an emacs_subr. >>>> If Lisp signals or throws, `funcall' returns NULL. >>> >>> I suggest some other value or indication of that. NULL is a valid >>> return value, so usurping it for errors might be too harsh. >> >> No it isn't. Qnil is distinct from NULL in this model because >> emacs_value is not a Lisp_Object in disguise. Qnil is not special here. > > I wasn't thinking about Qnil. I simply don't see why it is a good > idea to forbid funcall from returning NULL in a normal case. We're not preventing functions from returning NULL in the general case. We're deciding that NULL is not a valid value of emacs_value type. This property makes NULL a good candidate for an error sentinel return value for functions that would otherwise return valid emacs_value values. >>>> `intern' also does the obvious thing. >>> >>> Do we need 'unintern' as well? >> >> Modules can call unintern through Lisp. > > Then why provide 'intern'? It, too, can be called from Lisp. Modules have no way other than `intern' of getting an emacs_value that corresponds to a known symbol. They can call `unintern' by first interning the symbol "unintern", then calling it. >>>> emacs_value (*type_of)( >>>> emacs_env* env, >>>> emacs_value value); >>>> >>>> Like Lisp type-of: returns a symbol. >>> >>> What is a "symbol", from the module's C code POV? >> >> It's an emacs_value. You can compare symbols (by calling `eq'), call >> them as functions, or use them as function arguments. That's sufficient. >> >> Come to think of it, though, we do need a C-level `eq'. > > Why not simply return a C enumeration type? Why make the set of elisp primitive types part of the ABI? We already have a way to refer to symbols. There's no need to an enum, which would just be a redundant way of naming types. >>> . direct access to buffer text (using buffer-substring means consing >>> a lot of strings) >> >> Is that really a problem for the use cases we want to support? > > It could be a problem for a module that processes buffer text. > >>> . not sure how will a module "provide" its feature >> >> It doesn't. You don't require a module: you load it. Most modules will >> come with a small Lisp wrapper, just like Python modules. > > So do we _require_ a Lisp wrapper? Otherwise, how would Emacs know > whether the module is loaded or not? By path, I imagine. Why don't you have this problem with (load "myfile.el")? I'm not opposed to hooking modules into the provide-and-require machinery, but I don't see a particular need either. >>> One thing that's inconvenient is the need to drag the environment >>> pointer through all the calls. Why exactly is that needed? >> >> Modules have no other way of accessing Emacs internals. Dragging one >> parameter through the system isn't that bad and lets us sanely track >> which module is doing what. > > The environment must be known to the module, that's for sure. But why > does it have to be plugged into every call to every interface > function? How else are the interface functions supposed to know the module for which they're being called? >>> Also, the buffer returned by find-file when it returns normally is >>> lost here, isn't it? >> >> Sure. It's just a tiny example, and the returned buffer itself is still >> GCed. > > That's not what bothered me. I don't understand how will the module > receive that return value in the first place. An additional argument > to funcall, perhaps? funcall returns an emacs_value corresponding to the value the called function returned. Here's an alternate implementation of emacs_find_file: emacs_value emacs_find_file(emacs_env* env, const char* filename) { emacs_value e_filename = env->make_string(env, filename); if(env->error_check(env)) return NULL; emacs_value e_find_file = env->intern(env, "find-file"); if(env->error_check(env)) return NULL; return env->funcall(env, e_find_file, &e_filename, 1); } Now emacs_find_file returns NULL on error (with error information set in the environment) and an emacs_value on success. The returned value corresponds to whatever find-file returned, so in this case, it's a buffer. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-16 20:01 ` Daniel Colascione @ 2015-02-17 15:43 ` Eli Zaretskii 2015-02-17 17:46 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-17 15:43 UTC (permalink / raw) To: Daniel Colascione; +Cc: stephen_leake, emacs-devel > Date: Mon, 16 Feb 2015 12:01:40 -0800 > From: Daniel Colascione <dancol@dancol.org> > CC: stephen_leake@stephe-leake.org, emacs-devel@gnu.org > > >>> This approach requires us to change the size each time we change the > >>> layout, even if the change itself leaves the size intact. Using a > >>> version field doesn't have this disadvantage. > >> > >> Emacs is allowed to pass a new version of the runtime and context > >> structures to modules expecting old versions. That can only work if the > >> structures are append-only, so `size' is adequate here. > > > > I understand that, but appending members does not necessarily increase > > the size of the struct, due to alignment, bit fields, etc. > > If it's just a table of function pointers and everything has natural > alignment, adding members will increase the size. Having to include only function pointers is also a kind of limitation inherent to this method. I guess I just don't understand why you didn't go with a version field. What are its disadvantages? The value can be generated automatically, so it isn't more error-prone than the size. > Say do_frobricate has address 0xA3B41234. Implementation-wise, the value > `frobricate` that `make_function' returned is a Lisp closure that > essentially looks like this: > > (lambda (&rest args) (%do-module-call frobricate-module 0xA3B41234 2 2 > args)) > > %do-module-call then clears the pending-error information, packs its > arguments into a C array, and calls 0xA3B41234 like this: > > emacs_subr module_function = (module_function) 0xA3B41234; > result = module_function(some_env, args, nargs); It's the arguments that I was talking about. AFAIU, you are saying that %do-module-call takes arguments, which are normal Lisp_Object values, generates the indirection table for them, which stores _pointers_ to the actual arguments, then puts those pointers into a C array, and calls 0xA3B41234. Is that correct? If so, I guess I don't see why we would need all that complexity and extra processing. Why not put the original Lisp_Object values into the args[] array to begin with? > >>> What about the doc string? > >> > No: that's silly. I'm saying that creating a globally-named function in > Emacs has two parts: 1) create the actual _function object_. 2) bind > that function object to a name by setting some symbol's function slot to > that function object. We can do step #2 entirely in Lisp code that the > module calls, and we can set a documentation property at this time. It's > only step #1 that requires a magical incantation. > > I've only described the magical, ABI-relevant bits of the interface. In > order to make a module actually usable, we'll need glue, but since we > can implement this glue in Lisp and call it from module code using the > narrow interface I've described here, I'm not worried about it. Sorry, I'm still not out of the woods. Providing a doc string has nothing to do with calling the function. You need to have the doc string available even if you never call the function. The trigger for accessing the doc string is _outside_ of the module, by one of the help commands. So how does all this work in your scenario above, where we called make_function, which returned 'frobnicate', which is a value in the function slot of some Lisp object? Say now Emacs calls 'documentation-property' on that Lisp object or it calls 'documentation' on 'frobnicate' -- how will that produce a doc string? > >>> Do we need 'unintern' as well? > >> > >> Modules can call unintern through Lisp. > > > > Then why provide 'intern'? It, too, can be called from Lisp. > > Modules have no way other than `intern' of getting an emacs_value that > corresponds to a known symbol. They can call `unintern' by first > interning the symbol "unintern", then calling it. You mean, modules cannot use funcall to call Lisp functions, without some complicated dance with 'intern' before that? Why is that needed? why not let modules call Lisp functions by their string name, and do the 'intern' stuff on the Emacs side of the interface? > >>>> emacs_value (*type_of)( > >>>> emacs_env* env, > >>>> emacs_value value); > >>>> > >>>> Like Lisp type-of: returns a symbol. > >>> > >>> What is a "symbol", from the module's C code POV? > >> > >> It's an emacs_value. You can compare symbols (by calling `eq'), call > >> them as functions, or use them as function arguments. That's sufficient. > >> > >> Come to think of it, though, we do need a C-level `eq'. > > > > Why not simply return a C enumeration type? > > Why make the set of elisp primitive types part of the ABI? An enum is just a list of named integer values. Additions to that list make more values valid, that's all. How is that "part of the ABI" that could introduce incompatibility? OTOH, making the life of module writers harder on every turn is not a good way of encouraging modules. > >>> . not sure how will a module "provide" its feature > >> > >> It doesn't. You don't require a module: you load it. Most modules will > >> come with a small Lisp wrapper, just like Python modules. > > > > So do we _require_ a Lisp wrapper? Otherwise, how would Emacs know > > whether the module is loaded or not? > > By path, I imagine. What path is that? Where and how will Lisp code find it? > Why don't you have this problem with (load "myfile.el")? Because myfile.el normally does a (provide 'myfile), and then I can use featurep. > I'm not opposed to hooking modules into the provide-and-require > machinery, but I don't see a particular need either. The need is to have an easy way of checking that a module is available, without risking loading it twice, or having to jump through hoops. > >>> One thing that's inconvenient is the need to drag the environment > >>> pointer through all the calls. Why exactly is that needed? > >> > >> Modules have no other way of accessing Emacs internals. Dragging one > >> parameter through the system isn't that bad and lets us sanely track > >> which module is doing what. > > > > The environment must be known to the module, that's for sure. But why > > does it have to be plugged into every call to every interface > > function? > > How else are the interface functions supposed to know the module for > which they're being called? Why would the interface functions care? Which parts of the environment are needed for the interface to know about the module in order to do its job? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-17 15:43 ` Eli Zaretskii @ 2015-02-17 17:46 ` Aurélien Aptel 2015-02-17 17:50 ` Aurélien Aptel ` (3 more replies) 0 siblings, 4 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-02-17 17:46 UTC (permalink / raw) To: Eli Zaretskii Cc: Daniel Colascione, Stephen Leake, Emacs development discussions I'm with Eli on the versionning choice but it's just bike shedding at this point. Interning all the time seems tedious and probably (a bit?) slow but moving the interning on Emacs side won't change the slow part. At least on the module side you can do it once and reuse the result. Or maybe you shouldn't if the user changes the binding in the meantime? On Tue, Feb 17, 2015 at 4:43 PM, Eli Zaretskii <eliz@gnu.org> wrote: >> By path, I imagine. > > What path is that? Where and how will Lisp code find it? > >> Why don't you have this problem with (load "myfile.el")? > > Because myfile.el normally does a (provide 'myfile), and then I can > use featurep. > >> I'm not opposed to hooking modules into the provide-and-require >> machinery, but I don't see a particular need either. > > The need is to have an easy way of checking that a module is > available, without risking loading it twice, or having to jump through > hoops. We should call `provide' in the module (like in my module branch) using the API. Problem solved? Concerning docstrings, we just have to teach the makedoc utility how to extract them from this new module system. Then the module loading code can read that along with loading the module as it's done in my branch, where the doc string field of a Lisp_Subr can be a (cons "doc/file/path" offset) instead of simply <offset to the global DOC file>. So the real remaining issues are - module code is tedious to write because you have to check for errors all the time - interning all the time is slow, probably? (needs some testing) - <insert missing issues> Sorry, I'm sure I've overlooked some things, I'll re-read all the discussion later. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-17 17:46 ` Aurélien Aptel @ 2015-02-17 17:50 ` Aurélien Aptel 2015-02-17 18:04 ` Daniel Colascione ` (2 subsequent siblings) 3 siblings, 0 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-02-17 17:50 UTC (permalink / raw) To: Eli Zaretskii Cc: Daniel Colascione, Stephen Leake, Emacs development discussions On Tue, Feb 17, 2015 at 6:46 PM, Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: > maybe you shouldn't if the user changes the binding in the meantime? err.. intrening returns a symbol nevermind that part. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-17 17:46 ` Aurélien Aptel 2015-02-17 17:50 ` Aurélien Aptel @ 2015-02-17 18:04 ` Daniel Colascione 2015-02-18 3:29 ` Stefan Monnier 2015-02-17 18:06 ` Dynamic loading progress Eli Zaretskii 2015-02-18 0:55 ` Stephen J. Turnbull 3 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-02-17 18:04 UTC (permalink / raw) To: Aurélien Aptel, Eli Zaretskii Cc: Stephen Leake, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 2561 bytes --] On 02/17/2015 09:46 AM, Aurélien Aptel wrote: > I'm with Eli on the versionning choice but it's just bike shedding at > this point. I'm worried about what happens during long Emacs development cycles. Say we're developing Emacs 26 and during its yearlong release cycle, we add to emacs_env a `make_foo' in month 3 and an `access_bar' hook in month 6. I want to make an distribute a module that uses `make_foo' if it's available. If we have some kind of explicit versioning enum, we'll probably have only one per Emacs release, so modules won't be able to detect that `foo' is available until we release Emacs 26. If we make the version date-based, we'll have a lot of different versions, and it'll be hard for a module author to figure out which constant they need to test against. A size field seems just right, since it automatically updates when and only when we add something to the struct. > Interning all the time seems tedious and probably (a bit?) slow but > moving the interning on Emacs side won't change the slow part. At > least on the module side you can do it once and reuse the result. Or > maybe you shouldn't if the user changes the binding in the meantime? I agree that interning all the time is tedious, but I don't intend module authors to use this interface directly. What I've described is just the narrow ABI-stable boundary between Emacs and modules; we can give module authors a richer "client" library, implemented in terms of the stable ABI, that itself doesn't need to ABI-stable (although we should try to make it source-compatible upwardly). I have a few ideas for making life easy for module authors. One idea is to make evaluating Lisp very easy. We can provide something like this: bool emacs_eval(emacs_env* env, const char* lisp, ...); Then module authors can write code like this: success = emacs_eval(env, "(put-text-property %v %v 'myproperty (myfunction))", value_min, value_max); Internally, we'd then call (using emacs_env::funcall) a function we'd define in Lisp in Emacs: (%module-eval "(put-text-property %v %v...)" <value_min> <value_max>) That function would then transform the %v substitutions to expressions like (nth module-eval-arguments 0) (nth module-eval-arguments 1)) And then call (let ((module-eval-arguments args)) (eval expression-from-module)) This interface isn't the most efficient thing in the world, but it's hard to be more convenient, and it's good enough for code that isn't executed frequently. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-17 18:04 ` Daniel Colascione @ 2015-02-18 3:29 ` Stefan Monnier 2015-02-28 18:20 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-02-18 3:29 UTC (permalink / raw) To: Daniel Colascione Cc: Aurélien Aptel, Eli Zaretskii, Stephen Leake, Emacs development discussions > I'm worried about what happens during long Emacs development > cycles. Say we're developing Emacs 26 and during its yearlong release > cycle, we add to emacs_env a `make_foo' in month 3 and an `access_bar' > hook in month 6. We don't provide any support for non-released version of Emacs other than "the latest on its branch", so once `access_bar' is added the intermediate situation where `make_foo'was added but `access_bar' wasn't simply doesn't exist anymore (that is, it may exist but any user of such an Emacs is expected to fix the problem by upgrading (or downgrading)). > A size field seems just right, since it automatically updates when and > only when we add something to the struct. IIUC there'd be a size field anyway,whether or not there's also a version field. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-18 3:29 ` Stefan Monnier @ 2015-02-28 18:20 ` Aurélien Aptel 2015-03-04 13:48 ` Stephen Leake ` (4 more replies) 0 siblings, 5 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-02-28 18:20 UTC (permalink / raw) To: Stefan Monnier Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions I've tried to implement modules using Daniel's plan. It turned out to be pretty easy, mostly because I'm more familiar with the Emacs codebase now and because it's a lot less intrusive than my previous attempt. It's not finished but I have a basic module working on linux. It's a proof of concept, basically. * fixnum <-> int64_t is the only type conversion supported * No memory management * No error handling * No optional compilation/configure option * No docstrings No special build instructions since nothing is ifdef'd. Once you have it running, you can build the sample module by running make in modules/basic/. $ ./src/emacs -Q (module-load "./modules/basic/basic.so") => t (basic-sum 2 2) => 4 The code is available on my github repo on the dynamic-modules-2 branch. The interesting parts are the API header, the runtime and the sample module. git repo: https://github.com/aaptel/emacs-dynamic-module.git browse online: https://github.com/aaptel/emacs-dynamic-module/commit/278f26a5e993f8cbf6784f35c5ea8aeb9ef04019 ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-28 18:20 ` Aurélien Aptel @ 2015-03-04 13:48 ` Stephen Leake 2015-03-04 22:34 ` Stefan Monnier ` (3 subsequent siblings) 4 siblings, 0 replies; 765+ messages in thread From: Stephen Leake @ 2015-03-04 13:48 UTC (permalink / raw) To: emacs-devel Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: > I've tried to implement modules using Daniel's plan. It turned out to > be pretty easy, mostly because I'm more familiar with the Emacs > codebase now and because it's a lot less intrusive than my previous > attempt. Thanks! I'm a little busy right now, but I'll look at this soon. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-28 18:20 ` Aurélien Aptel 2015-03-04 13:48 ` Stephen Leake @ 2015-03-04 22:34 ` Stefan Monnier 2015-03-04 22:39 ` Daniel Colascione 2015-03-05 17:19 ` Stephen Leake ` (2 subsequent siblings) 4 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-03-04 22:34 UTC (permalink / raw) To: Aurélien Aptel Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions > * fixnum <-> int64_t is the only type conversion supported Not sure I understand: can the C side see "Lisp_Object" (presumably as an opaque type)? Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-04 22:34 ` Stefan Monnier @ 2015-03-04 22:39 ` Daniel Colascione 2015-03-05 13:12 ` Aurélien Aptel ` (2 more replies) 0 siblings, 3 replies; 765+ messages in thread From: Daniel Colascione @ 2015-03-04 22:39 UTC (permalink / raw) To: Stefan Monnier, Aurélien Aptel Cc: Eli Zaretskii, Stephen Leake, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 365 bytes --] On 03/04/2015 02:34 PM, Stefan Monnier wrote: >> * fixnum <-> int64_t is the only type conversion supported > > Not sure I understand: can the C side see "Lisp_Object" (presumably as > an opaque type)? As I'm imagining the system, no. Access is indirected. That insulates C code from Emacs GC requirements and lets us easily support global references. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-04 22:39 ` Daniel Colascione @ 2015-03-05 13:12 ` Aurélien Aptel 2015-03-05 17:37 ` Paul Eggert 2015-04-20 23:38 ` Ted Zlatanov 2015-03-05 13:17 ` Aurélien Aptel 2015-03-06 5:14 ` Stefan Monnier 2 siblings, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-03-05 13:12 UTC (permalink / raw) To: Daniel Colascione Cc: Eli Zaretskii, Stephen Leake, Stefan Monnier, Emacs development discussions The dynamic-modules-2 branch is implemented from scratch (well, from the master branch) in case that wasn't clear. I'll summarize what the code is doing, to make sure with everyone I'm not doing anything wrong. Emacs core has a new module.c[0] file which provides various function pointers to modules via a struct (actually 2 struct, there's emacs_environment and emacs_runtime). These structs are defined in src/emacs_module.h [1]. A module has an emacs_module_init function which is called when the module is loaded. This function is passed an emacs_environment pointer which is used by the module to get a emacs_runtime pointer which has all the useful function pointers to interact with emacs. Lisp_Object are exposed via the emacs_value type which is opaque. From emacs_module.h: typedef void* emacs_value; To convert a Lisp_Objet to an emacs_value I simply cast, currently. From Emacs' module.c: static emacs_value module_make_fixnum (emacs_env *env, int64_t n) { return (emacs_value) make_number (n); } (let's just ignore the overflow and error checking for now and focus on the architecture) Daniel's last message made me understand the GC problem. Since emacs integers are stored directly "in" the Lisp_Object there's no problem with the GC because there's no memory to free. But for other more complex types (where the Lisp_Object is actually a pointer) an emacs_value stored by the module can become invalid between 2 emacs->module calls because it was garbage collected. So what I should do is make another Lisp_Object-like union type that owns its memory (ie. not handled by the GC) and use that as emacs_value (still opaque for the module). Correct? 0: https://github.com/aaptel/emacs-dynamic-module/blob/dynamic-modules-2/src/module.c 1: https://github.com/aaptel/emacs-dynamic-module/blob/dynamic-modules-2/src/emacs_module.h ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-05 13:12 ` Aurélien Aptel @ 2015-03-05 17:37 ` Paul Eggert 2015-03-05 18:19 ` Aurélien Aptel 2015-04-20 23:38 ` Ted Zlatanov 1 sibling, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-03-05 17:37 UTC (permalink / raw) To: Aurélien Aptel; +Cc: Emacs development discussions On 03/05/2015 05:12 AM, Aurélien Aptel wrote: > typedef void* emacs_value; > > To convert a Lisp_Objet to an emacs_value I simply cast I don't see how this can work reliably if EMACS_INT and 'void *' have different widths. You should be able to reproduce the problem on x86 with 'configure --with-wide-int'. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-05 17:37 ` Paul Eggert @ 2015-03-05 18:19 ` Aurélien Aptel 0 siblings, 0 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-03-05 18:19 UTC (permalink / raw) To: Paul Eggert; +Cc: Emacs development discussions On Thu, Mar 5, 2015 at 6:37 PM, Paul Eggert <eggert@cs.ucla.edu> wrote: > I don't see how this can work reliably if EMACS_INT and 'void *' have > different widths. You should be able to reproduce the problem on x86 with > 'configure --with-wide-int'. I guess we could use (u)int64_t instead of void* then? Anyway passing casted Lisp_Object won't work for pointer-type Lisp_Object because of the GC. We'll most likely have to use pointers to an intermediate struct (cf my previous post). Fast access to types directly encoded in the Lisp_Object address would be nice though. I feel like we're just going to re-implement Lisp_Object x) ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-05 13:12 ` Aurélien Aptel 2015-03-05 17:37 ` Paul Eggert @ 2015-04-20 23:38 ` Ted Zlatanov 2015-04-21 8:58 ` Aurélien Aptel 1 sibling, 1 reply; 765+ messages in thread From: Ted Zlatanov @ 2015-04-20 23:38 UTC (permalink / raw) To: emacs-devel On Thu, 5 Mar 2015 14:12:29 +0100 Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: AA> The dynamic-modules-2 branch is implemented from scratch (well, from AA> the master branch) in case that wasn't clear. ... AA> 0: https://github.com/aaptel/emacs-dynamic-module/blob/dynamic-modules-2/src/module.c AA> 1: https://github.com/aaptel/emacs-dynamic-module/blob/dynamic-modules-2/src/emacs_module.h I like it. Can you provide a simple example in the branch of how it would be used from both sides? I can restart the testing and keep it in sync with the Emacs repo again. Thanks Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-04-20 23:38 ` Ted Zlatanov @ 2015-04-21 8:58 ` Aurélien Aptel 2015-04-21 14:14 ` Ted Zlatanov 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-04-21 8:58 UTC (permalink / raw) To: Emacs development discussions On Tue, Apr 21, 2015 at 1:38 AM, Ted Zlatanov <tzz@lifelogs.com> wrote: > I like it. Can you provide a simple example in the branch of how it > would be used from both sides? I can restart the testing and keep it in > sync with the Emacs repo again. It's already in there: https://github.com/aaptel/emacs-dynamic-module/tree/dynamic-modules-2/modules/basic ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-04-21 8:58 ` Aurélien Aptel @ 2015-04-21 14:14 ` Ted Zlatanov 2015-04-22 16:25 ` Stephen Leake 0 siblings, 1 reply; 765+ messages in thread From: Ted Zlatanov @ 2015-04-21 14:14 UTC (permalink / raw) To: emacs-devel On Tue, 21 Apr 2015 10:58:06 +0200 Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: AA> On Tue, Apr 21, 2015 at 1:38 AM, Ted Zlatanov <tzz@lifelogs.com> wrote: >> I like it. Can you provide a simple example in the branch of how it >> would be used from both sides? I can restart the testing and keep it in >> sync with the Emacs repo again. AA> It's already in there: AA> https://github.com/aaptel/emacs-dynamic-module/tree/dynamic-modules-2/modules/basic Right! As far as the coding style and barriers this enforces, I think it's just right. Thanks to you and Dan Colascione and the others for working on it. As far as capabilities, the basic module should have a string exchange, as you've started to implement in `copy_string_contents' and `make_string'. I think it's impossible to move forward without that. I would go simple for now: always make a copy of the string using UTF-8 encoding in the args, assuming that the majority of C modules can deal with it, and we can stop worrying about string sharing and encoding for now (we can revisit them later). We should free the copy right after calling so the module doesn't have to free it. If you agree, maybe you should make a specific type for UTF-8 encoded strings so we can support others in the future (byte array, wchars, etc.). I think `plugin_is_GPL_compatible' should be a float indicating the GPL version. Maybe even a char[] to express flavors, from a constrained set of choices. Let me know what you think. I'll hold off pushing and testing for now but am happy to proceed on your command. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-04-21 14:14 ` Ted Zlatanov @ 2015-04-22 16:25 ` Stephen Leake 2015-04-22 17:15 ` Stefan Monnier ` (2 more replies) 0 siblings, 3 replies; 765+ messages in thread From: Stephen Leake @ 2015-04-22 16:25 UTC (permalink / raw) To: emacs-devel Ted Zlatanov <tzz@lifelogs.com> writes: > On Tue, 21 Apr 2015 10:58:06 +0200 Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: > > AA> On Tue, Apr 21, 2015 at 1:38 AM, Ted Zlatanov <tzz@lifelogs.com> wrote: >>> I like it. Can you provide a simple example in the branch of how it >>> would be used from both sides? I can restart the testing and keep it in >>> sync with the Emacs repo again. > > AA> It's already in there: > > AA> https://github.com/aaptel/emacs-dynamic-module/tree/dynamic-modules-2/modules/basic > > Right! > > As far as the coding style and barriers this enforces, I think it's just > right. Thanks to you and Dan Colascione and the others for working on > it. +1 > As far as capabilities, the basic module should have a string exchange, > as you've started to implement in `copy_string_contents' > and `make_string'. I think it's impossible to move forward without > that. For my parser module, I plan on calling the elisp lexer currently in ada-mode (which uses the sytax class information, forward-sexp, etc). That avoids copying the entire buffer text to the module, or dealing with direct access. I haven't got it working yet, so I'm not entirely sure that will be fast enough, but the lexer is a small portion of the full parser. > I would go simple for now: always make a copy of the string using UTF-8 > encoding in the args, assuming that the majority of C modules can deal > with it, and we can stop worrying about string sharing and encoding for > now (we can revisit them later). We should free the copy right after > calling so the module doesn't have to free it. I'm not clear who is freeing what here; the module API does need to document that clearly. We also need to document the GCPRO issues; for example, given the following call: emacs_value pairs[] = { env->make_fixnum (env, 1), ada_grammar_names[341], /* statement-start */ env->make_fixnum (env, 2), ada_grammar_names[342], /* statement-other */ env->make_fixnum (env, 4), ada_grammar_names[343] /* statement-end */ }; emacs_value args_2[] = { env->funcall (env, vector, 6, pairs) }; env->funcall (env, wisi_statement_action, 1, args_2); where 'wisi_statement_action' is an elisp function that uses 'pairs' to set text properties, should the module do GCPRO around the funcall, or does the funcall handle that? Also, we need to do something about the doc strings for lisp objects declared in modules. I don't think they need to be available before the module is loaded; if a particular author wants that, they can define an elisp wrapper with autoloads. At a minimum, default doc string should be provided that gives a pointer to the module source code. > I think `plugin_is_GPL_compatible' should be a float indicating the GPL > version. Maybe even a char[] to express flavors, from a constrained set > of choices. +1 for the char[]. The variable could be named 'license_terms', so it could be used by non-GPL in special circumstances. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-04-22 16:25 ` Stephen Leake @ 2015-04-22 17:15 ` Stefan Monnier 2015-05-03 10:43 ` Ted Zlatanov 2015-05-03 10:55 ` Ted Zlatanov 2015-08-19 14:27 ` Ted Zlatanov 2 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-04-22 17:15 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel > where 'wisi_statement_action' is an elisp function that uses 'pairs' to > set text properties, should the module do GCPRO around the funcall, or > does the funcall handle that? I think it'd be OK to simply say that dynamic loading can only be used on platforms that use the conservative stack scanning (i.e. don't need GCPRO). AFAIK all platforms that matter use conservative stack scanning. >> I think `plugin_is_GPL_compatible' should be a float indicating the GPL >> version. Maybe even a char[] to express flavors, from a constrained set >> of choices. > +1 for the char[]. The variable could be named 'license_terms', so it > could be used by non-GPL in special circumstances. It took us many years to find a system with which the FSF is comfortable, so I'm vetoing any bikeshedding on this name. `plugin_is_GPL_compatible' it will be. If you want it to be finer grained to detect incompatibilities between Emacs's GPLv3+ and a plugin that's GPLv2-only, then please discuss it with Richard (and maybe the GCC guys, since IIUC they use the exact same system). In the mean we'll just check the presence of this symbol rather than any value associated with it. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-04-22 17:15 ` Stefan Monnier @ 2015-05-03 10:43 ` Ted Zlatanov 0 siblings, 0 replies; 765+ messages in thread From: Ted Zlatanov @ 2015-05-03 10:43 UTC (permalink / raw) To: emacs-devel On Wed, 22 Apr 2015 13:15:52 -0400 Stefan Monnier <monnier@IRO.UMontreal.CA> wrote: SM> It took us many years to find a system with which the FSF is SM> comfortable, so I'm vetoing any bikeshedding on this name. SM> `plugin_is_GPL_compatible' it will be. SM> If you want it to be finer grained to detect incompatibilities between SM> Emacs's GPLv3+ and a plugin that's GPLv2-only, then please discuss it SM> with Richard (and maybe the GCC guys, since IIUC they use the exact SM> same system). SM> In the mean we'll just check the presence of this symbol rather than any SM> value associated with it. I wasn't aware it was a GNU thing already. Thank you for explaining. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-04-22 16:25 ` Stephen Leake 2015-04-22 17:15 ` Stefan Monnier @ 2015-05-03 10:55 ` Ted Zlatanov 2015-05-03 23:44 ` Stephen Leake 2015-05-04 0:16 ` Stefan Monnier 2015-08-19 14:27 ` Ted Zlatanov 2 siblings, 2 replies; 765+ messages in thread From: Ted Zlatanov @ 2015-05-03 10:55 UTC (permalink / raw) To: emacs-devel On Wed, 22 Apr 2015 11:25:51 -0500 Stephen Leake <stephen_leake@stephe-leake.org> wrote: SL> Ted Zlatanov <tzz@lifelogs.com> writes: >> I would go simple for now: always make a copy of the string using UTF-8 >> encoding in the args, assuming that the majority of C modules can deal >> with it, and we can stop worrying about string sharing and encoding for >> now (we can revisit them later). We should free the copy right after >> calling so the module doesn't have to free it. SL> I'm not clear who is freeing what here; the module API does need to SL> document that clearly. "We" was Emacs. So the module API will state "passed strings are a temporary copy that will be freed for you, so don't free() them, but if you do, it won't break anything." SL> We also need to document the GCPRO issues; ... SL> should the module do GCPRO around the funcall, or does the funcall SL> handle that? IMHO Emacs should manage memory, period. Any time modules are given that responsibility, it's an opportunity for bugs and a premature optimization. Perhaps we'll find it necessary later to give this responsibility to some modules, but let's not do it now. SL> Also, we need to do something about the doc strings for lisp objects SL> declared in modules. I don't think they need to be available before the SL> module is loaded; if a particular author wants that, they can define an SL> elisp wrapper with autoloads. SL> At a minimum, default doc string should be provided that gives a pointer SL> to the module source code. I have no strong opinion on this, but your suggestion sounds fine. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-05-03 10:55 ` Ted Zlatanov @ 2015-05-03 23:44 ` Stephen Leake 2015-05-04 10:09 ` Ted Zlatanov 2015-05-04 0:16 ` Stefan Monnier 1 sibling, 1 reply; 765+ messages in thread From: Stephen Leake @ 2015-05-03 23:44 UTC (permalink / raw) To: emacs-devel Ted Zlatanov <tzz@lifelogs.com> writes: > On Wed, 22 Apr 2015 11:25:51 -0500 Stephen Leake <stephen_leake@stephe-leake.org> wrote: > > SL> Ted Zlatanov <tzz@lifelogs.com> writes: > > > SL> We also need to document the GCPRO issues; > ... > SL> should the module do GCPRO around the funcall, or does the funcall > SL> handle that? > > IMHO Emacs should manage memory, period. Any time modules are given that > responsibility, it's an opportunity for bugs and a premature > optimization. Perhaps we'll find it necessary later to give this > responsibility to some modules, but let's not do it now. That makes sense, but doesn't actually answer my question. Does the current funcall implementation handle GCPRO on the args adequately, or does it need to be improved/GCPRO added in the module? -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-05-03 23:44 ` Stephen Leake @ 2015-05-04 10:09 ` Ted Zlatanov 0 siblings, 0 replies; 765+ messages in thread From: Ted Zlatanov @ 2015-05-04 10:09 UTC (permalink / raw) To: emacs-devel On Sun, 03 May 2015 18:44:05 -0500 Stephen Leake <stephen_leake@stephe-leake.org> wrote: SL> Ted Zlatanov <tzz@lifelogs.com> writes: >> On Wed, 22 Apr 2015 11:25:51 -0500 Stephen Leake <stephen_leake@stephe-leake.org> wrote: >> SL> Ted Zlatanov <tzz@lifelogs.com> writes: >> >> SL> We also need to document the GCPRO issues; >> ... SL> should the module do GCPRO around the funcall, or does the funcall SL> handle that? >> >> IMHO Emacs should manage memory, period. Any time modules are given that >> responsibility, it's an opportunity for bugs and a premature >> optimization. Perhaps we'll find it necessary later to give this >> responsibility to some modules, but let's not do it now. SL> That makes sense, but doesn't actually answer my question. SL> Does the current funcall implementation handle GCPRO on the args SL> adequately, or does it need to be improved/GCPRO added in the module? (You mean the module-side funcall, right? Not the one built in Emacs?) Looking at it, it appears to only pass atomic data types that don't need GC protection right now, so the implementation for passing strings is not done. But I'd love to get some comments from Aurélien, he must have plans and ideas. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-05-03 10:55 ` Ted Zlatanov 2015-05-03 23:44 ` Stephen Leake @ 2015-05-04 0:16 ` Stefan Monnier 2015-05-04 10:03 ` Ted Zlatanov 1 sibling, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-05-04 0:16 UTC (permalink / raw) To: emacs-devel >>> I would go simple for now: always make a copy of the string using UTF-8 >>> encoding in the args, assuming that the majority of C modules can deal >>> with it, and we can stop worrying about string sharing and encoding for >>> now (we can revisit them later). We should free the copy right after >>> calling so the module doesn't have to free it. I don't like this idea of making copies just to avoid memory management. Especially since we already have a GC available to solve this problem. But I missed the context, so I don't really know what I'm talking about. SL> We also need to document the GCPRO issues; > ... SL> should the module do GCPRO around the funcall, or does the funcall SL> handle that? > IMHO Emacs should manage memory, period. Any time modules are given that > responsibility, it's an opportunity for bugs and a premature > optimization. It's an illusion to think that all memory management can be moved to the Emacs side. But I think the best way to move most of it to the Emacs side is to let the modules benefit from the Emacs's GC, and hence export the "GC protocol" to the modules side. As mentioned elsewhere, we probably want to skip the GCPRO part of the protocol (and hence only support dynamic loading on those platforms where we use conservative stack scanning), so as to move even more of the memory management onto the Emacs's side. SL> Also, we need to do something about the doc strings for lisp objects SL> declared in modules. I don't think they need to be available before the SL> module is loaded; if a particular author wants that, they can define an SL> elisp wrapper with autoloads. Agreed. The same holds for .el files. The only difference is that for .el files we have autoload.el which can auto-generate the "wrapper with autoloads". Maybe we could create a similar system for dynloaded packages, but there's no hurry for it. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-05-04 0:16 ` Stefan Monnier @ 2015-05-04 10:03 ` Ted Zlatanov 0 siblings, 0 replies; 765+ messages in thread From: Ted Zlatanov @ 2015-05-04 10:03 UTC (permalink / raw) To: emacs-devel On Sun, 03 May 2015 20:16:03 -0400 Stefan Monnier <monnier@iro.umontreal.ca> wrote: >> IMHO Emacs should manage memory, period. Any time modules are given that >> responsibility, it's an opportunity for bugs and a premature >> optimization. SM> It's an illusion to think that all memory management can be moved to the SM> Emacs side. But I think the best way to move most of it to the Emacs SM> side is to let the modules benefit from the Emacs's GC, and hence export SM> the "GC protocol" to the modules side. Exactly. I should have said "Emacs should manage its memory." Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-04-22 16:25 ` Stephen Leake 2015-04-22 17:15 ` Stefan Monnier 2015-05-03 10:55 ` Ted Zlatanov @ 2015-08-19 14:27 ` Ted Zlatanov 2015-08-20 15:19 ` Stephen Leake 2 siblings, 1 reply; 765+ messages in thread From: Ted Zlatanov @ 2015-08-19 14:27 UTC (permalink / raw) To: emacs-devel; +Cc: Aurélien Aptel, Stephen Leake Stephen, Aurélien, the dynamic module progress seems stalled. Could you summarize what's missing or blocking it? Back in May 2015 we discussed it but I don't see anything happening afterwards. Thanks Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-08-19 14:27 ` Ted Zlatanov @ 2015-08-20 15:19 ` Stephen Leake 2015-08-23 19:12 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Stephen Leake @ 2015-08-20 15:19 UTC (permalink / raw) To: emacs-devel Ted Zlatanov <tzz@lifelogs.com> writes: > Stephen, Aurélien, the dynamic module progress seems stalled. Could you > summarize what's missing or blocking it? Back in May 2015 we discussed > it but I don't see anything happening afterwards. I got stuck with Ada exception handling issues, then got sidetracked by various other things. As far as issues blocking a merge to master, I've documented the ones I know about as FIXMEs in module.c. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-08-20 15:19 ` Stephen Leake @ 2015-08-23 19:12 ` Aurélien Aptel 2015-08-23 22:26 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-08-23 19:12 UTC (permalink / raw) To: Stephen Leake, Daniel Colascione; +Cc: Emacs development discussions Hi all, Daniel, Following Ted last off-list email I looked again at the module code. Thanks again to Daniel for the API design proposal you did few month ago and the general explanations, it was insightful and it really helped me. I would really like to have the module API in emacs 25 so I recently revisited my code and re-read the dynamic loading threads on emacs-devel but I'm still stuck on the memory aspect. I'll re-explain briefly the problem: The module API [1] lets module writer make new Lisp_Object (hidden as opaque pointers named 'emacs_value') via make_<type>(), funcall(), type_of() and intern() functions. But if a module function calls core Emacs functions, those functions it turn might call the GC, which would free and invalidate the objects made by the module. Here are 2 examples of the same problem: - Local values which are created/can-be-freed inside the module function. a = make_string("foo") b = make_string("bar") len = funcall(eval, 1, [length_sym, b]) // a (and b?) might be invalid now if the GC was triggered inside the funcall call. In the core Emacs code, we have the GCPRO macro to deal with that use-case. - Values created and reused between 2 module calls. emacs_value global_a; module_func_A() global_a = make_string("a") module_func_B(): // global_a might be invalid now if the GC was triggered between func_A and func_B return global_a In the core Emacs code, global_a is usually a defvar. Daniel was talking about tables mapping emacs_value to Lisp_Object, and having manual memory management in the module API. But I'm not sure I understood what you meant. Here's another proposition (which might just be what you were trying to explain): We add a hash table at the GC root that maps module names to a list of values currently owned by the module. Any markable/collectable emacs_value (all Lisp_Object types except for numeric ones basically) created by the module API are added to that hash table (appended at the module's list). When a module doesn't need a value anymore, it explicitly calls a function in the module API that removes it from the module's list. The GC walks the object tree like usual, including the module hash table. This is more or less what GCPRO/UNGCPRO does, I think (temporally add objects to the GC root). And if remember correctly Stefan was against exposing it in the module API. I've proposed a hash table to know which values a module owns. That way we can sort of "unload" a module by simply removing the module entry from the hash table (we still have to deal with unbinding the module's functions). The GC will do the rest. Any feedback, other ideas, welcome. 1: https://github.com/aaptel/emacs-dynamic-module/blob/dynamic-modules-2/src/emacs_module.h ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-08-23 19:12 ` Aurélien Aptel @ 2015-08-23 22:26 ` Stefan Monnier 2015-08-23 22:45 ` Aurélien Aptel 2015-08-24 2:13 ` Tom Tromey 0 siblings, 2 replies; 765+ messages in thread From: Stefan Monnier @ 2015-08-23 22:26 UTC (permalink / raw) To: Aurélien Aptel Cc: Daniel Colascione, Stephen Leake, Emacs development discussions > - Local values which are created/can-be-freed inside the module function. > > a = make_string("foo") > b = make_string("bar") > len = funcall(eval, 1, [length_sym, b]) > // a (and b?) might be invalid now if the GC was triggered inside > the funcall call. > > In the core Emacs code, we have the GCPRO macro to deal with that use-case. GCPRO is only needed if we don't use conservative stack scanning. Conservative stack scanning is used by 99.9% of Emacs builds (so much so that there are always latent bugs in the GCPRO code because it sees very little testing), so I think it's perfectly acceptable to ignore the remaining 0.1%. IOW we don't need to worry about local Lisp_Object values: they'll be found by the conservative stack scanner. > - Values created and reused between 2 module calls. > > emacs_value global_a; > > module_func_A() > global_a = make_string("a") > > module_func_B(): > // global_a might be invalid now if the GC was triggered > between func_A and func_B > return global_a > > In the core Emacs code, global_a is usually a defvar. We just need to export the equivalent of "staticpro" (ideally, this should keep track of which module called it, so that we can automatically "unpro"tect those vars when/if the module is unloaded). > Daniel was talking about tables mapping emacs_value to Lisp_Object, I don't want to have to convert between emacs_value and Lisp_Object, they should be one and the same. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-08-23 22:26 ` Stefan Monnier @ 2015-08-23 22:45 ` Aurélien Aptel 2015-08-23 23:37 ` Paul Eggert 2015-08-24 19:11 ` Stefan Monnier 2015-08-24 2:13 ` Tom Tromey 1 sibling, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-08-23 22:45 UTC (permalink / raw) To: Stefan Monnier Cc: Daniel Colascione, Stephen Leake, Emacs development discussions On Mon, Aug 24, 2015 at 12:26 AM, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > GCPRO is only needed if we don't use conservative stack scanning. > Conservative stack scanning is used by 99.9% of Emacs builds (so much so > that there are always latent bugs in the GCPRO code because it sees very > little testing), so I think it's perfectly acceptable to ignore the > remaining 0.1%. Ok, we can always check for conservative scanning at compile to enable modules. > We just need to export the equivalent of "staticpro" (ideally, this > should keep track of which module called it, so that we can > automatically "unpro"tect those vars when/if the module is unloaded). So if I understand correctly, with conservative scanning there's no need to call UNGCPRO? > I don't want to have to convert between emacs_value and Lisp_Object, > they should be one and the same. Ok, I'll keep casting Lisp_Object to void* then. Since module writer will often need to use Lisp_Object as handle for their own struct pointers, I was thinking adding a way to register finalizer functions to the API. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-08-23 22:45 ` Aurélien Aptel @ 2015-08-23 23:37 ` Paul Eggert 2015-08-24 19:11 ` Stefan Monnier 1 sibling, 0 replies; 765+ messages in thread From: Paul Eggert @ 2015-08-23 23:37 UTC (permalink / raw) To: Aurélien Aptel, Stefan Monnier Cc: Daniel Colascione, Stephen Leake, Emacs development discussions Aurélien Aptel wrote: > Ok, I'll keep casting Lisp_Object to void* then. That's not necessarily correct, as the cast could lose information, e.g., 32-bit platforms configured --with-wide-int. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-08-23 22:45 ` Aurélien Aptel 2015-08-23 23:37 ` Paul Eggert @ 2015-08-24 19:11 ` Stefan Monnier 1 sibling, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2015-08-24 19:11 UTC (permalink / raw) To: Aurélien Aptel Cc: Daniel Colascione, Stephen Leake, Emacs development discussions > Ok, we can always check for conservative scanning at compile to > enable modules. Exactly. >> We just need to export the equivalent of "staticpro" (ideally, this >> should keep track of which module called it, so that we can >> automatically "unpro"tect those vars when/if the module is unloaded). > So if I understand correctly, with conservative scanning there's no > need to call UNGCPRO? Indeed, neither GCPRO nor GCUNPRO. > Since module writer will often need to use Lisp_Object as handle for > their own struct pointers, I was thinking adding a way to register > finalizer functions to the API. We'll probably want ways to define new types and/or to register finalizers, indeed. But that can wait. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-08-23 22:26 ` Stefan Monnier 2015-08-23 22:45 ` Aurélien Aptel @ 2015-08-24 2:13 ` Tom Tromey 2015-08-24 19:13 ` Stefan Monnier 1 sibling, 1 reply; 765+ messages in thread From: Tom Tromey @ 2015-08-24 2:13 UTC (permalink / raw) To: Stefan Monnier Cc: Aurélien Aptel, Daniel Colascione, Stephen Leake, Emacs development discussions Stefan> IOW we don't need to worry about local Lisp_Object values: they'll be Stefan> found by the conservative stack scanner. Is there a reason to keep GCPRO around? Tom ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-08-24 2:13 ` Tom Tromey @ 2015-08-24 19:13 ` Stefan Monnier 2015-08-24 20:19 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-08-24 19:13 UTC (permalink / raw) To: Tom Tromey Cc: Aurélien Aptel, Daniel Colascione, Stephen Leake, Emacs development discussions Stefan> IOW we don't need to worry about local Lisp_Object values: they'll be Stefan> found by the conservative stack scanner. > Is there a reason to keep GCPRO around? IIUC there are still some situations where we build without conservative stack scanning. We should probably go and enable it everywhere. If noone complains that should indicate that indeed conservative stack scanning is used (or ca be used) everywhere, so we could drop the GCPROs. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-08-24 19:13 ` Stefan Monnier @ 2015-08-24 20:19 ` Paul Eggert 2015-08-25 4:35 ` David Kastrup 2015-08-25 22:03 ` Stefan Monnier 0 siblings, 2 replies; 765+ messages in thread From: Paul Eggert @ 2015-08-24 20:19 UTC (permalink / raw) To: Stefan Monnier, Tom Tromey Cc: Aurélien Aptel, Daniel Colascione, Stephen Leake, Emacs development discussions On 08/24/2015 12:13 PM, Stefan Monnier wrote: > IIUC there are still some situations where we build without conservative > stack scanning. > > We should probably go and enable it everywhere. We did that last year, before 24.4 came out. GC_MARK_STACK is defined to be GC_MAKE_GCPROS_NOOPS unless the builder compiles with -DGC_MARK_STACK=somethingelse. I think nobody does that except perhaps when testing. > If noone complains that > should indicate that indeed conservative stack scanning is used (or ca > be used) everywhere, so we could drop the GCPROs. As far as I know, nobody has complained, so we could drop the GCPROs now if you like. Perhaps we should hold a wake? Should I bring a bottle of poteen? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-08-24 20:19 ` Paul Eggert @ 2015-08-25 4:35 ` David Kastrup 2015-08-25 22:03 ` Stefan Monnier 1 sibling, 0 replies; 765+ messages in thread From: David Kastrup @ 2015-08-25 4:35 UTC (permalink / raw) To: Paul Eggert Cc: Daniel Colascione, Emacs development discussions, Stefan Monnier, Aurélien Aptel, Tom Tromey, Stephen Leake Paul Eggert <eggert@cs.ucla.edu> writes: > On 08/24/2015 12:13 PM, Stefan Monnier wrote: >> IIUC there are still some situations where we build without conservative >> stack scanning. >> >> We should probably go and enable it everywhere. > > We did that last year, before 24.4 came out. GC_MARK_STACK is defined > to be GC_MAKE_GCPROS_NOOPS unless the builder compiles with > -DGC_MARK_STACK=somethingelse. I think nobody does that except > perhaps when testing. > >> If noone complains that >> should indicate that indeed conservative stack scanning is used (or ca >> be used) everywhere, so we could drop the GCPROs. > > As far as I know, nobody has complained, so we could drop the GCPROs > now if you like. > > Perhaps we should hold a wake? Should I bring a bottle of poteen? Just have people point at each other, that should keep them awake. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-08-24 20:19 ` Paul Eggert 2015-08-25 4:35 ` David Kastrup @ 2015-08-25 22:03 ` Stefan Monnier 2015-08-27 2:29 ` Paul Eggert 1 sibling, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-08-25 22:03 UTC (permalink / raw) To: Paul Eggert Cc: Aurélien Aptel, Stephen Leake, Tom Tromey, Daniel Colascione, Emacs development discussions > We did that last year, before 24.4 came out. Wait... what's that bell ringing in the distance? > As far as I know, nobody has complained, so we could drop the GCPROs > now if you like. Indeed. > Perhaps we should hold a wake? Definitely. There are still many details to figure out. Incineration of inhumation? Open casket? Should we keep it private? Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-08-25 22:03 ` Stefan Monnier @ 2015-08-27 2:29 ` Paul Eggert 2015-08-27 10:17 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-08-27 2:29 UTC (permalink / raw) To: Stefan Monnier Cc: Aurélien Aptel, Stephen Leake, Tom Tromey, Daniel Colascione, Emacs development discussions Stefan Monnier wrote: > Open casket? I was thinking more along the lines of a limestone sarcophagus, Egyptian style. I gave it a shot in master commit 60d1b18734fff144f1608da6228d60e4bda7b24c, so there should no longer be any need for GCPRO1 etc. in C source. I hope this gives us one less thing to worry about with dynamic loading. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-08-27 2:29 ` Paul Eggert @ 2015-08-27 10:17 ` Aurélien Aptel 2015-09-12 19:38 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-08-27 10:17 UTC (permalink / raw) To: Paul Eggert Cc: Stephen Leake, Tom Tromey, Daniel Colascione, Stefan Monnier, Emacs development discussions On Thu, Aug 27, 2015 at 4:29 AM, Paul Eggert <eggert@cs.ucla.edu> wrote: > I gave it a shot in master commit 60d1b18734fff144f1608da6228d60e4bda7b24c, > so there should no longer be any need for GCPRO1 etc. in C source. I hope > this gives us one less thing to worry about with dynamic loading. Cool! I was recently thinking of writing coccinelle [1] checks for unreleased GCPRO calls.. Guess it's not needed anymore :) 1: http://coccinelle.lip6.fr/ ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-08-27 10:17 ` Aurélien Aptel @ 2015-09-12 19:38 ` Aurélien Aptel 2015-09-12 20:42 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-09-12 19:38 UTC (permalink / raw) To: Paul Eggert Cc: Stephen Leake, Tom Tromey, Daniel Colascione, Stefan Monnier, Emacs development discussions Quick update: I only have the error handling left to implement from the API. I'm not sure on how to catch error/signal and return to the module code. I've added a basic portable dynamic loader layer (directly calling the native loading function) so it doesn't have to depend on libtool. Some of the remaining stuff to do: * configure/ifdef machinery to enable/disable the feature * expose a way to store arbitrary pointers in an emacs_value, and maybe implement finalizers. * add doc strings support * start thinking about how we want to package modules The problem with finalizer is they can't be used as destructors since the GC is not guaranteed to be called at the end of every dynamic/lexical scope (or is it?). But maybe that's a non-problem as long as it's documented. The rest of the things to do (except for the packaging thing) should be relatively easy since I've basically already done them in my first attempt at dynamic modules. I've also tried to build Emacs on a windows vm at work using Stephen Leake how-to but it fails at the configure stage saying that the build system is not supported (pc-i686-mingw-32 ...from memory). I have to look more into it. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-12 19:38 ` Aurélien Aptel @ 2015-09-12 20:42 ` Stefan Monnier 2015-09-12 23:11 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-09-12 20:42 UTC (permalink / raw) To: Aurélien Aptel Cc: Stephen Leake, Emacs development discussions, Paul Eggert, Tom Tromey, Daniel Colascione > I only have the error handling left to implement from the API. I'm not > sure on how to catch error/signal and return to the module code. Can you give us more details about you mean by the above. Are you talking about how to handle things like calls to Fsignal, or to Fthrow, or how to provide access to unwind-protect and condition-case in to the module's? > The problem with finalizer is they can't be used as destructors since > the GC is not guaranteed to be called at the end of every > dynamic/lexical scope (or is it?). Indeed it's not guaranteed at all. It's not even guaranteed that when you call the GC, all dead objects will be collected. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-12 20:42 ` Stefan Monnier @ 2015-09-12 23:11 ` Aurélien Aptel 2015-09-13 12:54 ` Philipp Stephani 2015-09-13 13:14 ` Stefan Monnier 0 siblings, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-09-12 23:11 UTC (permalink / raw) To: Stefan Monnier Cc: Stephen Leake, Emacs development discussions, Paul Eggert, Tom Tromey, Daniel Colascione On Sat, Sep 12, 2015 at 10:42 PM, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > Can you give us more details about you mean by the above. > Are you talking about how to handle things like calls to Fsignal, or to > Fthrow, or how to provide access to unwind-protect and condition-case in > to the module's? The case where a module calls an emacs function that ends up calling signal/error. I don't know enough about how signaling and unwind-protect work. It's just black stack magic for me right now :) I think we just need to implement funcall (from the module API) like this: global error = 0 module_funcall(fun, args): // wrap (protect?) this with the right code // - to keep the control // - set ret to nil and error to 1 in case of error ret = Ffuncall(fun, args) return ret The error is accessible via error_get(), error_clear() and error_check() in the module API. error_get() is currently redundant with error_check() unless we decide to return detailed errors. I didn't think about the case where a module calls Fthrow but my guess is it will just work. I have to test thoroughly what I have already anyway, I'll see if it works. > Indeed it's not guaranteed at all. It's not even guaranteed that when you > call the GC, all dead objects will be collected. Ok. Finalizers are better than nothing I guess. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-12 23:11 ` Aurélien Aptel @ 2015-09-13 12:54 ` Philipp Stephani 2015-09-13 13:14 ` Stefan Monnier 1 sibling, 0 replies; 765+ messages in thread From: Philipp Stephani @ 2015-09-13 12:54 UTC (permalink / raw) To: Aurélien Aptel, Stefan Monnier Cc: Tom Tromey, Paul Eggert, Stephen Leake, Daniel Colascione, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 2835 bytes --] Aurélien Aptel <aurelien.aptel+emacs@gmail.com> schrieb am So., 13. Sep. 2015 um 01:11 Uhr: > On Sat, Sep 12, 2015 at 10:42 PM, Stefan Monnier > <monnier@iro.umontreal.ca> wrote: > > Can you give us more details about you mean by the above. > > Are you talking about how to handle things like calls to Fsignal, or to > > Fthrow, or how to provide access to unwind-protect and condition-case in > > to the module's? > > The case where a module calls an emacs function that ends up calling > signal/error. I don't know enough about how signaling and > unwind-protect work. It's just black stack magic for me right now :) > > They use longjmp, which doesn't work in modules. Your implementation needs to make sure that no longjmp ever escapes to module code, i.e. that none of the stackframes skipped by longjmp can lie inside a module. See what Daniel wrote above: "When Emacs calls a module function, the current thread's pending-error flag will be clear. When that module returns to Emacs, if the thread's pending-error flag is set, Emacs signals the condition corresponding to the current thread's error information. When the module calls an Emacs routine that would ordinarily signal, Emacs catches the signal at the stack frame just before control flow would return to the module, sets the pending-error flag, and returns to the module normally." > I think we just need to implement funcall (from the module API) like this: > > global error = 0 > > module_funcall(fun, args): > // wrap (protect?) this with the right code > // - to keep the control > // - set ret to nil and error to 1 in case of error > Here you probably need to call both internal_catch and internal_condition_case. > ret = Ffuncall(fun, args) > > return ret > > The error is accessible via error_get(), error_clear() and > error_check() in the module API. error_get() is currently redundant > with error_check() unless we decide to return detailed errors. > > What do you mean with 'detailed errors'? At a minimum users need access to the handler type (condition-case or catch), the catch tag, the error symbol, and the error data. Most likely the stacktrace should also be provided. > I didn't think about the case where a module calls Fthrow but my guess > is it will just work. > It uses a different handler type and therefore will probably not work out of the box unless you call internal_catch. > > > Indeed it's not guaranteed at all. It's not even guaranteed that when > you > > call the GC, all dead objects will be collected. > > Ok. Finalizers are better than nothing I guess. > > Why would you need finalizers at all? There are usually wrong and useless in languages with nondeterministic garbage collection. [-- Attachment #2: Type: text/html, Size: 4026 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-12 23:11 ` Aurélien Aptel 2015-09-13 12:54 ` Philipp Stephani @ 2015-09-13 13:14 ` Stefan Monnier 2015-09-13 13:19 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-09-13 13:14 UTC (permalink / raw) To: Aurélien Aptel Cc: Stephen Leake, Emacs development discussions, Paul Eggert, Tom Tromey, Daniel Colascione > The case where a module calls an emacs function that ends up calling > signal/error. OK, what are you worried about w.r.t that case? > I don't know enough about how signaling and unwind-protect work. It's > just black stack magic for me right now :) Fsignal works using longjmp. unwind-protect (and dynamic let-bindings) works by adding things onto a stack which Fsignal will run just prior to calling longjmp. > I think we just need to implement funcall (from the module API) like this: > global error = 0 > module_funcall(fun, args): > // wrap (protect?) this with the right code > // - to keep the control > // - set ret to nil and error to 1 in case of error > ret = Ffuncall(fun, args) > return ret > The error is accessible via error_get(), error_clear() and > error_check() in the module API. error_get() is currently redundant > with error_check() unless we decide to return detailed errors. I don't understand what kind of error handling you have in mind. How/why/when would we use things like error_get, error_clear, etc...? > I didn't think about the case where a module calls Fthrow but my guess > is it will just work. I have to test thoroughly what I have already > anyway, I'll see if it works. Fthrow uses the same technique as Fsignal, and I think your intuition is right: it should just work (for both). Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-13 13:14 ` Stefan Monnier @ 2015-09-13 13:19 ` Philipp Stephani 2015-09-13 20:31 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-09-13 13:19 UTC (permalink / raw) To: Stefan Monnier, Aurélien Aptel Cc: Tom Tromey, Paul Eggert, Stephen Leake, Daniel Colascione, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 2122 bytes --] Stefan Monnier <monnier@iro.umontreal.ca> schrieb am So., 13. Sep. 2015 um 15:14 Uhr: > > The case where a module calls an emacs function that ends up calling > > signal/error. > > OK, what are you worried about w.r.t that case? > It's not possible to skip frames in module code using longjmp, so module_funcall needs to set up handlers before calling Ffuncall. > > > I don't know enough about how signaling and unwind-protect work. It's > > just black stack magic for me right now :) > > Fsignal works using longjmp. unwind-protect (and dynamic let-bindings) > works by adding things onto a stack which Fsignal will run just prior to > calling longjmp. > > > I think we just need to implement funcall (from the module API) like > this: > > > global error = 0 > > > module_funcall(fun, args): > > // wrap (protect?) this with the right code > > // - to keep the control > > // - set ret to nil and error to 1 in case of error > > ret = Ffuncall(fun, args) > > > return ret > > > The error is accessible via error_get(), error_clear() and > > error_check() in the module API. error_get() is currently redundant > > with error_check() unless we decide to return detailed errors. > > I don't understand what kind of error handling you have in mind. > How/why/when would we use things like error_get, error_clear, etc...? > Because setjmp/longjmp and therefore Fthrow/Fsignal don't work, you need to design a different error handling API that doesn't rely on non-local jumps. There are three options: return values, output parameters, thread-local state. All three have their pros and cons; Daniel opted for the third. The error_... functions are needed to access that thread-local state. > > > I didn't think about the case where a module calls Fthrow but my guess > > is it will just work. I have to test thoroughly what I have already > > anyway, I'll see if it works. > > Fthrow uses the same technique as Fsignal, and I think your intuition is > right: it should just work (for both). > No, it can't. See Daniel's initial posting where he designed the module API. [-- Attachment #2: Type: text/html, Size: 2941 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-13 13:19 ` Philipp Stephani @ 2015-09-13 20:31 ` Stefan Monnier 2015-09-13 20:33 ` Daniel Colascione 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-09-13 20:31 UTC (permalink / raw) To: Philipp Stephani Cc: Paul Eggert, Daniel Colascione, Emacs development discussions, Aurélien Aptel, Tom Tromey, Stephen Leake > It's not possible to skip frames in module code using longjmp, so Why not? Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-13 20:31 ` Stefan Monnier @ 2015-09-13 20:33 ` Daniel Colascione 2015-09-14 1:58 ` Stefan Monnier 2015-09-14 3:43 ` Stephen J. Turnbull 0 siblings, 2 replies; 765+ messages in thread From: Daniel Colascione @ 2015-09-13 20:33 UTC (permalink / raw) To: Stefan Monnier, Philipp Stephani Cc: Aurélien Aptel, Tom Tromey, Paul Eggert, Stephen Leake, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 317 bytes --] On 09/13/2015 01:31 PM, Stefan Monnier wrote: >> It's not possible to skip frames in module code using longjmp, so > > Why not? Because most C code isn't expecting to be unwound. Forcing non-local flow control on module code is completely unacceptable. Emacs needs to return with an error indication set. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-13 20:33 ` Daniel Colascione @ 2015-09-14 1:58 ` Stefan Monnier 2015-09-14 2:08 ` Daniel Colascione 2015-09-28 15:12 ` Philipp Stephani 2015-09-14 3:43 ` Stephen J. Turnbull 1 sibling, 2 replies; 765+ messages in thread From: Stefan Monnier @ 2015-09-14 1:58 UTC (permalink / raw) To: Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Aurélien Aptel, Tom Tromey, Stephen Leake >>> It's not possible to skip frames in module code using longjmp, so >> Why not? > Because most C code isn't expecting to be unwound. > Forcing non-local flow control on module code is completely > unacceptable. Emacs needs to return with an error indication set. Hmm... I'm still not sure what's the issue. AFAICT, the only odd case I can think of is the following: 1- Emacs calls some module code via the new API. 2- This code (which is Emacs-specific) will know about Fthrow. 3- It may call some non-Emacs-specific code from some other library. 4- This non-Emacs-specific code calls back to some Emacs-specific function. 5- This Emacs-specific function calls Fthrow/Fsignal. Where the problem only shows if/when we reach point 5. This problem can be handled between 4 and 5 by using an appropriate internal_condition_case. Is there some other situation you're thinking of? Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 1:58 ` Stefan Monnier @ 2015-09-14 2:08 ` Daniel Colascione 2015-09-14 4:18 ` Stefan Monnier 2015-09-28 15:12 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-09-14 2:08 UTC (permalink / raw) To: Stefan Monnier Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Aurélien Aptel, Tom Tromey, Stephen Leake [-- Attachment #1: Type: text/plain, Size: 2071 bytes --] On 09/13/2015 06:58 PM, Stefan Monnier wrote: >>>> It's not possible to skip frames in module code using longjmp, so >>> Why not? >> Because most C code isn't expecting to be unwound. >> Forcing non-local flow control on module code is completely >> unacceptable. Emacs needs to return with an error indication set. > > Hmm... I'm still not sure what's the issue. > > AFAICT, the only odd case I can think of is the following: > > 1- Emacs calls some module code via the new API. > 2- This code (which is Emacs-specific) will know about Fthrow. > 3- It may call some non-Emacs-specific code from some other library. > 4- This non-Emacs-specific code calls back to some Emacs-specific function. > 5- This Emacs-specific function calls Fthrow/Fsignal. > > Where the problem only shows if/when we reach point 5. > > This problem can be handled between 4 and 5 by using an appropriate > internal_condition_case. > > Is there some other situation you're thinking of? Nobody is going to consider that case. It'll be hard enough to get developers to properly unwind their own code, especially because we're only talking about a case that's active when things go wrong. Of course we can make non-local control flow work: it works well enough inside Emacs. I'm objecting to this approach because it's a bug machine, especially without the Emacs Lisp and GC machinery. It breaks C++ RAII, because there's no way the longjmp out of Emacs can run C++ destructors. Rust cleanups, and lots of other runtimes are similarly broken. You're asking developers to cope with Emacs deciding simply never to return from most module API calls. That's okay for Emacs internals, but it's very awkward for code having to talk to Emacs. There's no need to do it that way either. Storing the exception information thread-locally (which means globally unless we ever actually get threads) works with C-ABI semantics, is easier to reason about for developers not used to Emacs internals, and provides just as much error information. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 2:08 ` Daniel Colascione @ 2015-09-14 4:18 ` Stefan Monnier 2015-09-14 4:37 ` Daniel Colascione 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-09-14 4:18 UTC (permalink / raw) To: Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Aurélien Aptel, Tom Tromey, Stephen Leake >> AFAICT, the only odd case I can think of is the following: >> >> 1- Emacs calls some module code via the new API. >> 2- This code (which is Emacs-specific) will know about Fthrow. >> 3- It may call some non-Emacs-specific code from some other library. >> 4- This non-Emacs-specific code calls back to some Emacs-specific function. >> 5- This Emacs-specific function calls Fthrow/Fsignal. >> >> Where the problem only shows if/when we reach point 5. >> >> This problem can be handled between 4 and 5 by using an appropriate >> internal_condition_case. >> >> Is there some other situation you're thinking of? > Nobody is going to consider that case. Which other case are you thinking about then? > It'll be hard enough to get developers to properly unwind their own > code, especially because we're only talking about a case that's active > when things go wrong. Of course we can make non-local control flow > work: it works well enough inside Emacs. You lost me. > I'm objecting to this approach because it's a bug machine, especially What is "this approach"? > without the Emacs Lisp and GC machinery. AFAIK we do have the Elisp and the GC machinery available. > It breaks C++ RAII, because there's no way the longjmp out of Emacs > can run C++ destructors. This seems to refer to the "point 5" above. As mentioned it's easy to prevent the longjmp from escaping back into the surrounding non-Emacs (e.g. C++) code. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 4:18 ` Stefan Monnier @ 2015-09-14 4:37 ` Daniel Colascione 2015-09-14 12:14 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-09-14 4:37 UTC (permalink / raw) To: Stefan Monnier Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Aurélien Aptel, Tom Tromey, Stephen Leake [-- Attachment #1: Type: text/plain, Size: 3491 bytes --] On 09/13/2015 09:18 PM, Stefan Monnier wrote: >> It'll be hard enough to get developers to properly unwind their own >> code, especially because we're only talking about a case that's active >> when things go wrong. Of course we can make non-local control flow >> work: it works well enough inside Emacs. > > You lost me. > >> I'm objecting to this approach because it's a bug machine, especially > > What is "this approach"? Specifically, I don't think Emacs public module API functions should ever return non-locally. "This approach" means longjmping out to condition-case instead of returning normally from Emacs module API functions. > >> without the Emacs Lisp and GC machinery. > > AFAIK we do have the Elisp and the GC machinery available. Yes, but the whole point of the module system is to access non-Emacs libraries, and these libraries will have its own resource tracking systems, which won't integrate with the Emacs GC core. Longjmp in the Emacs core is convenient: if you want to make an Emacs Lisp string, you can call make_string, and even if the next line of the program longjmps, the GC will take care of releasing the resources associated with that string. Imagine if you had to individually arrange to call free on both the success and error paths for every string you wanted to allocate --- that's what life will will be like for module authors. I don't imagine most modules will be using Emacs GCed resources for their own data, so they'll have to arrange for cleanups manually. >> It breaks C++ RAII, because there's no way the longjmp out of Emacs >> can run C++ destructors. > > This seems to refer to the "point 5" above. As mentioned it's easy to > prevent the longjmp from escaping back into the surrounding non-Emacs > (e.g. C++) code. I agree that it's possible. I don't agree that it's easy. If the interface is like internal_condition_case, developers will have to define another C-level function to act as an longjmp barrier, and they'll have to do that for every call from their module to the Emacs core. That's a lot of boilerplate. I'm afraid that developers will skip this boilerplate and just make Emacs API calls directly, leading to the presence of latent bugs that are hard to diagnose and fix. This sloppy approach will appear to work fine, but things can go very wrong in rare circumstances. The problems I foresee are of the form "Emacs crashes when I hit C-g with just the right timing", or "Emacs leaks memory if find-file fails while this module calls it". You can imagine Emacs deadlocking if a module takes a long, Emacs longjmps past that lock's release, and then later (perhaps much later) we try to take that lock and never acquire it. Sure, it's possible to introduce similar bugs by not checking error codes or some global error flag. The difference is that the danger is better-understood (since many more C programs use error codes or error flags than use longjmp), and we can diagnose the problems arising from a failed error check more reliably than we can diagnose the problems that can arise from a failed stack cleanup. For example, if we use a global error flag, and we see an Emacs module API function called with this error flag set, we can abort immediately, pinpointing the problem. Or we can fail the call, warn the user, or do anything else sensible. We can't even _detect_ the kind of damage produced by missing stack cleanups. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 4:37 ` Daniel Colascione @ 2015-09-14 12:14 ` Stefan Monnier 2015-09-14 14:36 ` Stephen Leake 2015-09-14 15:14 ` Daniel Colascione 0 siblings, 2 replies; 765+ messages in thread From: Stefan Monnier @ 2015-09-14 12:14 UTC (permalink / raw) To: Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Aurélien Aptel, Tom Tromey, Stephen Leake > Yes, but the whole point of the module system is to access non-Emacs > libraries, But the issue only comes up once these non-Emacs libraries call back to Emacs functions (i.e. step 5 in my example). So only those calls need to be protected somehow from non-local exits. > and these libraries will have its own resource tracking > systems, which won't integrate with the Emacs GC core. Right, just like the libraries we currently link to from core Emacs (libxml, libgnutls, libX, ...). They *very rarely* call back to Emacs functions. > Imagine if you had to individually arrange to call free on both the > success and error paths for every string you wanted to allocate --- > that's what life will will be like for module authors. No. Only for those who choose to use use manually-managed data. > I don't imagine most modules will be using Emacs GCed resources for I do. And I think we should encourage them to do so. For that reason we want to add finalizers, for example. >> This seems to refer to the "point 5" above. As mentioned it's easy to >> prevent the longjmp from escaping back into the surrounding non-Emacs >> (e.g. C++) code. > I agree that it's possible. I don't agree that it's easy. Of course it is. We already do that in Emacs's core with things like safe_call. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 12:14 ` Stefan Monnier @ 2015-09-14 14:36 ` Stephen Leake 2015-09-14 15:17 ` Eli Zaretskii 2015-09-14 15:14 ` Daniel Colascione 1 sibling, 1 reply; 765+ messages in thread From: Stephen Leake @ 2015-09-14 14:36 UTC (permalink / raw) To: emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: >> Yes, but the whole point of the module system is to access non-Emacs >> libraries, > > But the issue only comes up once these non-Emacs libraries call back to > Emacs functions (i.e. step 5 in my example). So only those calls need > to be protected somehow from non-local exits. I think Daniel's point is that most module developers will not be aware of this issue, and will be totally lost when it occurs. In addition, how many libraries document whether they are "longjmp safe"? I suspect that actually depends on compiler options, so it's up to the packagers to ensure it. Imagine someone used to writing Java code, with the attitude "the language is totally safe, I don't need to worry about details"; now they try to write an Emacs module, calling out to Java code all over the place. Chaos ensues, and Emacs gets another bad wrap as "unusable". So if the Emacs module API can be made to support those developers, it would be a good thing. I think his point is valid, although it would be nice for expert module developers to be able to bypass the "safe call" if it becomes a performance issue. I don't think we can make writing an Emacs module as easy as writing a Java class, but we should consider doing as much as we can to make it easier/safer for the novice. On the other hand, being forced to handle an exception instead of remembering to check a status code is a proven win. So perhaps there is a way to make all module developers aware of this issue; a well written, short "module developer's checklist" would help here. >> Imagine if you had to individually arrange to call free on both the >> success and error paths for every string you wanted to allocate --- >> that's what life will will be like for module authors. > > No. Only for those who choose to use use manually-managed data. Some module authors won't realize they've chosen that. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 14:36 ` Stephen Leake @ 2015-09-14 15:17 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-09-14 15:17 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel > From: Stephen Leake <stephen_leake@stephe-leake.org> > Date: Mon, 14 Sep 2015 09:36:10 -0500 > > Stefan Monnier <monnier@iro.umontreal.ca> writes: > > >> Yes, but the whole point of the module system is to access non-Emacs > >> libraries, > > > > But the issue only comes up once these non-Emacs libraries call back to > > Emacs functions (i.e. step 5 in my example). So only those calls need > > to be protected somehow from non-local exits. > > I think Daniel's point is that most module developers will not be aware > of this issue, and will be totally lost when it occurs. And Stefan's point is that such an occurrence is highly improbable, to say the least. > In addition, how many libraries document whether they are "longjmp > safe"? If the longjmp never happens, this is irrelevant. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 12:14 ` Stefan Monnier 2015-09-14 14:36 ` Stephen Leake @ 2015-09-14 15:14 ` Daniel Colascione 2015-09-14 17:48 ` Stefan Monnier 2015-09-15 2:56 ` Stephen J. Turnbull 1 sibling, 2 replies; 765+ messages in thread From: Daniel Colascione @ 2015-09-14 15:14 UTC (permalink / raw) To: Stefan Monnier Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Aurélien Aptel, Tom Tromey, Stephen Leake [-- Attachment #1: Type: text/plain, Size: 2964 bytes --] Why are you so insistent on using non-local exits for error handling? Representing errors more conventionally is cheap. If there's even a small chance that I'm right about the safety and maintainability advantages of using purely local exits, why not err on the side of caution? AFAICS, there's no advantage to using non-local exits and plenty of risks. On 09/14/2015 05:14 AM, Stefan Monnier wrote: >> Yes, but the whole point of the module system is to access non-Emacs >> libraries, > > But the issue only comes up once these non-Emacs libraries call back to > Emacs functions (i.e. step 5 in my example). So only those calls need > to be protected somehow from non-local exits. Calls back to Emacs functions will be fairly common, because modules use these functions to manipulate Emacs data on behalf of their own callers. Any of these functions can quit. What you're imagining will be a rare case will in fact be common. I also don't think it's correct that the Emacs-specific module code will work properly in the presence of modules. You're supposing too much patience and knowledge on the part of third-party module authors who'll want to provide bindings not only for Emacs, but for other systems as well. >> and these libraries will have its own resource tracking >> systems, which won't integrate with the Emacs GC core. > > Right, just like the libraries we currently link to from core Emacs > (libxml, libgnutls, libX, ...). They *very rarely* call back to > Emacs functions. > >> Imagine if you had to individually arrange to call free on both the >> success and error paths for every string you wanted to allocate --- >> that's what life will will be like for module authors. > > No. Only for those who choose to use use manually-managed data. Who will be common, because the entire point of writing modules is to work with the _non_-Emacs world. I can imagine one module that has both non-trivial calls back into Emacs and quite a bit of internal state in suitable for management with Emacs primitives. It's called Python. Modules aren't going to be limited to small data-centric thngs like libjpeg, and we shouldn't design the extension system in a way that discourages more complex kinds of integration. >> I don't imagine most modules will be using Emacs GCed resources for > > I do. > > And I think we should encourage them to do so. For that reason we want > to add finalizers, for example. > >>> This seems to refer to the "point 5" above. As mentioned it's easy to >>> prevent the longjmp from escaping back into the surrounding non-Emacs >>> (e.g. C++) code. >> I agree that it's possible. I don't agree that it's easy. > > Of course it is. We already do that in Emacs's core with things like > safe_call. safe_call blindly suppresses errors. Errors from module-invoked functions to propagate normally from the perspective of surrounding Lisp code. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 15:14 ` Daniel Colascione @ 2015-09-14 17:48 ` Stefan Monnier 2015-09-14 18:05 ` Daniel Colascione 2015-09-15 2:56 ` Stephen J. Turnbull 1 sibling, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-09-14 17:48 UTC (permalink / raw) To: Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Aurélien Aptel, Tom Tromey, Stephen Leake > Representing errors more conventionally is cheap. AFAIK "representing errors more conventionally" means wrapping every single function we pass to the module API. That's definitely not cheap in terms of performance. > If there's even a small chance that I'm right about the safety and > maintainability advantages of using purely local exits, Representing errors as exceptions also has advantages. > why not err on the side of caution? AFAICS, there's no advantage to > using non-local exits and plenty of risks. There are very many advantages, on the contrary. Also, I expect most module authors will be familiar with Emacs, and having to learn a different style will be an extra hindrance. >> But the issue only comes up once these non-Emacs libraries call back to >> Emacs functions (i.e. step 5 in my example). So only those calls need >> to be protected somehow from non-local exits. > Calls back to Emacs functions will be fairly common, because modules use > these functions to manipulate Emacs data on behalf of their own callers. > Any of these functions can quit. What you're imagining will be a rare > case will in fact be common. You're not talking about the "step 5" case. You're talking about the Emacs-specific module code calling Emacs functions. Indeed, this will be very common. But to write this code, you will have to know a fair bit about Emacs internals, anyway. It will not look like your "typical C++ code". > I also don't think it's correct that the Emacs-specific module code will > work properly in the presence of modules. You're supposing too much > patience and knowledge on the part of third-party module authors who'll > want to provide bindings not only for Emacs, but for other systems as well. I don't forsee droves of coders who no nothing about Emacs internals and who start writing third party modules. In any case, I think it would be easy to layer the kind of API you imagine on top of the kind of API I imagine, whereas the reverse seems to be much more difficult and/or much less efficient. So I'd rather we go with a straightforward lean API for a start. And we can develop an alternative API on top afterwards (it might even be possible to implement this alt-API as a module). >> Of course it is. We already do that in Emacs's core with things like >> safe_call. > safe_call blindly suppresses errors. You're nitpicking. Of course we'd use something slighly different which stores the error somewhere. Th point remains that it's easy to provide such a wrapper. > Errors from module-invoked functions to propagate normally from the > perspective of surrounding Lisp code. [ Is there a verb missing, maybe, I can't quite parse this, sorry. ] Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 17:48 ` Stefan Monnier @ 2015-09-14 18:05 ` Daniel Colascione 2015-09-15 0:55 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-09-14 18:05 UTC (permalink / raw) To: Stefan Monnier Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Aurélien Aptel, Tom Tromey, Stephen Leake [-- Attachment #1: Type: text/plain, Size: 5170 bytes --] On 09/14/2015 10:48 AM, Stefan Monnier wrote: >> Representing errors more conventionally is cheap. > > AFAIK "representing errors more conventionally" means wrapping every > single function we pass to the module API. That's definitely not cheap > in terms of performance. Yes, we need an internal condition-case at the boundary between the module API and the Emacs core. I can call setjmp 54 million times per second. (100000000 runs in 183ms.) Performance is simply not a problem. >> If there's even a small chance that I'm right about the safety and >> maintainability advantages of using purely local exits, > > Representing errors as exceptions also has advantages. Besides performance? Longjmp for error handling has an _expressiveness_ advantage in the Emacs core, but that's because we use GC data structures for everything. Not so with external modules. >> why not err on the side of caution? AFAICS, there's no advantage to >> using non-local exits and plenty of risks. > > There are very many advantages, on the contrary. In a non-local exit scheme intended for use with third-party code and not supported by any standardized exception system (like C++ exceptions or SEH), I see only risks. > > Also, I expect most module authors will be familiar with Emacs, and > having to learn a different style will be an extra hindrance. I expect them to be familiar with Emacs. There is no need to make module developers familiarize themselves with Emacs internals. The public API should insulate them from that. > >>> But the issue only comes up once these non-Emacs libraries call back to >>> Emacs functions (i.e. step 5 in my example). So only those calls need >>> to be protected somehow from non-local exits. >> Calls back to Emacs functions will be fairly common, because modules use >> these functions to manipulate Emacs data on behalf of their own callers. >> Any of these functions can quit. What you're imagining will be a rare >> case will in fact be common. > > You're not talking about the "step 5" case. You're talking about the > Emacs-specific module code calling Emacs functions. Indeed, this will be > very common. But to write this code, you will have to know a fair bit > about Emacs internals, anyway. It will not look like your "typical C++ > code". Why shouldn't it? We _can_ make it look just like typical C++ code, and to encourage module development, we should. Why make life harder for people? >> I also don't think it's correct that the Emacs-specific module code will >> work properly in the presence of modules. You're supposing too much >> patience and knowledge on the part of third-party module authors who'll >> want to provide bindings not only for Emacs, but for other systems as well. > > I don't forsee droves of coders who no nothing about Emacs internals and > who start writing third party modules. Plenty of developers know nothing about Java or Python or Ruby or C# or V8 internals and write native extensions for these systems. Supporting developers who know the Lisp side of Emacs and who don't want to be bothered working in core is one of the most important use cases of the module system. > > In any case, I think it would be easy to layer the kind of API you > imagine on top of the kind of API I imagine, whereas the reverse seems > to be much more difficult and/or much less efficient. On the contrary, layering a different non-local exit scheme on top of an error flag scheme is elegant. Imagine a C++ module library that throws a C++ exception upon returning from Emacs and seeing the error flag set, the translates (just before returning from C++ to Emacs) that C++ exception back into an Emacs error. Now you have a non-local error scheme that is exactly the right thing for both languages. > So I'd rather we go with a straightforward lean API for a start. > And we can develop an alternative API on top afterwards (it might even > be possible to implement this alt-API as a module). A local-exit-only API _is_ a lean API, at least from a semantics perspective. It's not surprising. The cost of the error flag machinery in terms of both performance and API specification space is minuscule as well. >>> Of course it is. We already do that in Emacs's core with things like >>> safe_call. >> safe_call blindly suppresses errors. > > You're nitpicking. Of course we'd use something slighly different which > stores the error somewhere. Th point remains that it's easy to provide > such a wrapper. So now we need some kind of explicit error propagation machinery *anyway*, plus we're making developers worry about non-local exits. Let's skip the latter part. > >> Errors from module-invoked functions to propagate normally from the >> perspective of surrounding Lisp code. > > [ Is there a verb missing, maybe, I can't quite parse this, sorry. ] s/to // I don't want C-g to break when module, core, and lisp frames are mingled on stacks, and I expect these situations to be fairly common, especially if we support modules with names like "python" and "guile". [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 18:05 ` Daniel Colascione @ 2015-09-15 0:55 ` Stefan Monnier 2015-09-15 1:06 ` Daniel Colascione ` (2 more replies) 0 siblings, 3 replies; 765+ messages in thread From: Stefan Monnier @ 2015-09-15 0:55 UTC (permalink / raw) To: Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Aurélien Aptel, Tom Tromey, Stephen Leake Just, FWIW we can keep talking about it, but my opinion is quite firmly made. I want the first API to provide access to the "naked" primitives with no condition-case wrapping. Stefan >>>>> "Daniel" == Daniel Colascione <dancol@dancol.org> writes: > On 09/14/2015 10:48 AM, Stefan Monnier wrote: >>> Representing errors more conventionally is cheap. >> >> AFAIK "representing errors more conventionally" means wrapping every >> single function we pass to the module API. That's definitely not cheap >> in terms of performance. > Yes, we need an internal condition-case at the boundary between the > module API and the Emacs core. I can call setjmp 54 million times per > second. (100000000 runs in 183ms.) Performance is simply not a problem. >>> If there's even a small chance that I'm right about the safety and >>> maintainability advantages of using purely local exits, >> >> Representing errors as exceptions also has advantages. > Besides performance? Longjmp for error handling has an _expressiveness_ > advantage in the Emacs core, but that's because we use GC data > structures for everything. Not so with external modules. >>> why not err on the side of caution? AFAICS, there's no advantage to >>> using non-local exits and plenty of risks. >> >> There are very many advantages, on the contrary. > In a non-local exit scheme intended for use with third-party code and > not supported by any standardized exception system (like C++ exceptions > or SEH), I see only risks. >> >> Also, I expect most module authors will be familiar with Emacs, and >> having to learn a different style will be an extra hindrance. > I expect them to be familiar with Emacs. There is no need to make module > developers familiarize themselves with Emacs internals. The public API > should insulate them from that. >> >>>> But the issue only comes up once these non-Emacs libraries call back to >>>> Emacs functions (i.e. step 5 in my example). So only those calls need >>>> to be protected somehow from non-local exits. >>> Calls back to Emacs functions will be fairly common, because modules use >>> these functions to manipulate Emacs data on behalf of their own callers. >>> Any of these functions can quit. What you're imagining will be a rare >>> case will in fact be common. >> >> You're not talking about the "step 5" case. You're talking about the >> Emacs-specific module code calling Emacs functions. Indeed, this will be >> very common. But to write this code, you will have to know a fair bit >> about Emacs internals, anyway. It will not look like your "typical C++ >> code". > Why shouldn't it? We _can_ make it look just like typical C++ code, and > to encourage module development, we should. Why make life harder for people? >>> I also don't think it's correct that the Emacs-specific module code will >>> work properly in the presence of modules. You're supposing too much >>> patience and knowledge on the part of third-party module authors who'll >>> want to provide bindings not only for Emacs, but for other systems as well. >> >> I don't forsee droves of coders who no nothing about Emacs internals and >> who start writing third party modules. > Plenty of developers know nothing about Java or Python or Ruby or C# or > V8 internals and write native extensions for these systems. Supporting > developers who know the Lisp side of Emacs and who don't want to be > bothered working in core is one of the most important use cases of the > module system. >> >> In any case, I think it would be easy to layer the kind of API you >> imagine on top of the kind of API I imagine, whereas the reverse seems >> to be much more difficult and/or much less efficient. > On the contrary, layering a different non-local exit scheme on top of an > error flag scheme is elegant. Imagine a C++ module library that throws a > C++ exception upon returning from Emacs and seeing the error flag set, > the translates (just before returning from C++ to Emacs) that C++ > exception back into an Emacs error. Now you have a non-local error > scheme that is exactly the right thing for both languages. >> So I'd rather we go with a straightforward lean API for a start. >> And we can develop an alternative API on top afterwards (it might even >> be possible to implement this alt-API as a module). > A local-exit-only API _is_ a lean API, at least from a semantics > perspective. It's not surprising. The cost of the error flag machinery > in terms of both performance and API specification space is minuscule as > well. >>>> Of course it is. We already do that in Emacs's core with things like >>>> safe_call. >>> safe_call blindly suppresses errors. >> >> You're nitpicking. Of course we'd use something slighly different which >> stores the error somewhere. Th point remains that it's easy to provide >> such a wrapper. > So now we need some kind of explicit error propagation machinery > *anyway*, plus we're making developers worry about non-local exits. > Let's skip the latter part. >> >>> Errors from module-invoked functions to propagate normally from the >>> perspective of surrounding Lisp code. >> >> [ Is there a verb missing, maybe, I can't quite parse this, sorry. ] > s/to // > I don't want C-g to break when module, core, and lisp frames are mingled > on stacks, and I expect these situations to be fairly common, especially > if we support modules with names like "python" and "guile". ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-15 0:55 ` Stefan Monnier @ 2015-09-15 1:06 ` Daniel Colascione 2015-09-24 12:45 ` Aurélien Aptel 2015-09-28 15:25 ` Philipp Stephani 2 siblings, 0 replies; 765+ messages in thread From: Daniel Colascione @ 2015-09-15 1:06 UTC (permalink / raw) To: Stefan Monnier Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Aurélien Aptel, Tom Tromey, Stephen Leake [-- Attachment #1: Type: text/plain, Size: 460 bytes --] On 09/14/2015 05:55 PM, Stefan Monnier wrote: > Just, FWIW we can keep talking about it, but my opinion is quite firmly > made. I want the first API to provide access to the "naked" primitives > with no condition-case wrapping. The "first API" being the one with which we have to maintain binary compatibility? Well, at least I haven't lost on the merits of the design. There's no shame in losing to "because I say so". I'll stop wasting my time. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-15 0:55 ` Stefan Monnier 2015-09-15 1:06 ` Daniel Colascione @ 2015-09-24 12:45 ` Aurélien Aptel 2015-09-24 13:58 ` Stefan Monnier 2015-09-28 15:35 ` Philipp Stephani 2015-09-28 15:25 ` Philipp Stephani 2 siblings, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-09-24 12:45 UTC (permalink / raw) To: Stefan Monnier Cc: Daniel Colascione, Emacs development discussions, Philipp Stephani, Paul Eggert, Tom Tromey, Stephen Leake Some updates. I haven't made any progress on errors. I was reading on condition-case, setjmp/longjmp and how it's used for signaling/throwing. I actually knew very little about it. I shouldnt be the one writing this stuff I think... Anyway I was looking into how I would set up a "catch-all" wrapping code so that we can implement a funcall that always returns and I still haven't figured it out. You said you would rather have an "unsafe" funcall that sometimes not return to module code so I will try to do that. And realisticly if we want this in emacs 25 it's the only way (I don't feel confident enough to do that bit properly and I'm the only one working on this). We can always fix it afterwards or simply have a "safe" and an "unsafe" version of funcall in the API. I personally think having a clean simple API from the module writer POV is better (least surprise principle) so I'm in favor of wrapping, in the long term. I think changing the API in the early stage is fine and I don't worry too much about binary API changes because it's only going to be used with GPL plugins (i.e. modules can be fixed and recompiled, most of the time). I've added [1] a tool that can generate modules basic code from templates (Makefile, source file, ERT test file) and can run module tests in batch. It's going to be easier to get started and easier for me to write tests. I've put everything in the modules/ subdir, I know its a bit messy having a python script there along with a lisp file (common elisp functions for module test) but it's my setup right now and it saves me time (i.e. deal with it! :). We can remove or change it afterwards if we want. Here's how you use it: # after successfully compiling emacs % cd modules % ./modhelp.py init modt-mymod writing modt-mymod/test.el... writing modt-mymod/Makefile... writing modt-mymod/modt-mymod.c... done! you can run ./modhelp.py test modt-mymod % ./modhelp.py test modt-mymod [*] ./modt-mymod: ------- start ------- [*] ./modt-mymod: running make gcc -ggdb3 -Wall -I../../src -fPIC -c modt-mymod.c gcc -shared -o modt-mymod.so modt-mymod.o ../../lib-src/make-docfile modt-mymod.c > modt-mymod.doc rm modt-mymod.o [*] ./modt-mymod: running test ../src/emacs -batch -L . -l ert -l ./modt-mymod/test.el -f ert-run-tests-batch Running 1 tests (2015-09-24 14:33:44+0200) passed 1/1 modt-mymod-fun-test Ran 1 tests, 1 results as expected (2015-09-24 14:33:44+0200) [*] 1/1 MODULES OK Running the `test` command without specifying the module tests all module. (Hm.. I just noticed modules makefiles were ignored/not commited by git. I've just fixed it) I've started working on the configure.ac to make module a build time option (still a WIP, I've only commited it to be able to work on it from other computers). 1: https://github.com/aaptel/emacs-dynamic-module/commit/46c5f032ebf49275e346cae015dc39cbe3f8ebea ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-24 12:45 ` Aurélien Aptel @ 2015-09-24 13:58 ` Stefan Monnier 2015-09-26 14:56 ` Aurélien Aptel 2015-09-28 15:35 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-09-24 13:58 UTC (permalink / raw) To: Aurélien Aptel Cc: Daniel Colascione, Emacs development discussions, Philipp Stephani, Paul Eggert, Tom Tromey, Stephen Leake > I haven't made any progress on errors. I was reading on > condition-case, setjmp/longjmp and how it's used for > signaling/throwing. I actually knew very little about it. I shouldnt > be the one writing this stuff I think... That's OK. We can add it later. > Anyway I was looking into how > I would set up a "catch-all" wrapping code so that we can implement a > funcall that always returns and I still haven't figured it out. You can grep for "safe_call" to get an idea. > You said you would rather have an "unsafe" funcall that sometimes not > return to module code so I will try to do that. IIUC you've done that already, because it requires no special effort. That's why it's the path I want to take first. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-24 13:58 ` Stefan Monnier @ 2015-09-26 14:56 ` Aurélien Aptel 2015-09-28 3:01 ` Stefan Monnier ` (2 more replies) 0 siblings, 3 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-09-26 14:56 UTC (permalink / raw) To: Stefan Monnier Cc: Daniel Colascione, Emacs development discussions, Philipp Stephani, Paul Eggert, Tom Tromey, Stephen Leake I've implemented signal() and I've made the module support configurable (disabled by default). Except for signal() all error related functions are unimplemented (they are not useful because funcall() doesn't return to module code on error right now). I've also added a signal test. The make_string() now takes the length of the string as a parameter. Right now module are loaded with `module-load'. I need to modify `load' so that it also looks for modules (which will make `require' work). How should module docstring be written? We either: * pick a new syntax and teach make-docfile how to parse it. This is the clean approach IMO, but it requires more work. We can use a sufficiently simple syntax so that it can be embedded in comments in other languages than C. * define DEFVAR/DEFUN macro in module API header file to a noop so that make-docfile can parse it as it is. As for the finalizer, I wanted to add a function in the API: /* Finalizer prototype */ typedef int (*emacs_finalizer_function)(void *ptr); emacs_value make_user_ptr (emacs_env *env, void *ptr, emacs_finalizer_function *fin); Or we can have a full "method table" with printer function and other things we might need in the future. Although It's a bit overkill with just finalizer/printer... /* Printer prototype */ typedef emacs_value (*emacs_printer_function)(void *ptr); /* User-ptr operations */ typedef struct { emacs_finalizer_function *fin; emacs_printer_function *print; /* ... */ } emacs_user_ptr_ops; emacs_value make_user_ptr (emacs_env *env, void *ptr, emacs_user_ptr_ops *ops); ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-26 14:56 ` Aurélien Aptel @ 2015-09-28 3:01 ` Stefan Monnier 2015-09-28 10:13 ` Aurélien Aptel 2015-09-28 15:57 ` Stephen Leake 2015-09-28 15:42 ` Philipp Stephani 2015-10-04 4:30 ` Tom Tromey 2 siblings, 2 replies; 765+ messages in thread From: Stefan Monnier @ 2015-09-28 3:01 UTC (permalink / raw) To: Aurélien Aptel Cc: Daniel Colascione, Emacs development discussions, Philipp Stephani, Paul Eggert, Tom Tromey, Stephen Leake > I've implemented signal() What means "implemented signal()"? You mean, you export Fsignal to the modules? > Except for signal() all error related functions are unimplemented > (they are not useful because funcall() doesn't return to module code > on error right now). I'm not sure what that means. What other error-related functions? How does this relate to whether or not "funcall() returns to module code on error right now"? What means "returns to module code"? Do you provide "cdr"? If so, what does it do when a module calls it on a string object? I'd expect it to signal the error and longjmp to the nearest condition-case that catches it (presumably from outside of the module code, unless the module code setup condition_case as well). > * pick a new syntax and teach make-docfile how to parse it. This is > the clean approach IMO, but it requires more work. We can use a > sufficiently simple syntax so that it can be embedded in comments in > other languages than C. > * define DEFVAR/DEFUN macro in module API header file to a noop so > that make-docfile can parse it as it is. You're talking about how to get docstrings from the source code, but I think we should expect Emacs to need/fetch them during "load" at which point we'll be looking at the compiled code. So the first question is where should those docstrings (regardless of whether they were found and prepared by make-docfile or by some new tool) be located? Inside the .so file? Is the source code which should be placed nearby? In some kind of separate DOC file? > Or we can have a full "method table" with printer function and other > things we might need in the future. Although It's a bit overkill with > just finalizer/printer... Even without a printer function, I think it makes sense at least to provide some kind of "type" information so that it's obvious when two "user objects" are "of the same type". The method table can play the role of a "type". Also, it might make sense to let Emacs build this "method table" object. So instead of exposing an emacs_user_ptr_ops structure, export a function which creates a pointer to such an object. This way the actual emacs_user_ptr_ops structure can more easily evolve, and Emacs can more easily fill the various slots with default values where applicable (e.g. one slot might point to the module that owns the object and might better be filled by the Emacs core than by the module itself). Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 3:01 ` Stefan Monnier @ 2015-09-28 10:13 ` Aurélien Aptel 2015-09-28 21:59 ` Davis Herring 2015-09-28 15:57 ` Stephen Leake 1 sibling, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-09-28 10:13 UTC (permalink / raw) To: Stefan Monnier Cc: Daniel Colascione, Emacs development discussions, Philipp Stephani, Paul Eggert, Tom Tromey, Stephen Leake I wrote what we agreed on... On Mon, Sep 28, 2015 at 5:01 AM, Stefan Monnier <monnier@iro.umontreal.ca> wrote: > What means "implemented signal()"? You mean, you export Fsignal to > the modules? yes >> Except for signal() all error related functions are unimplemented >> (they are not useful because funcall() doesn't return to module code >> on error right now). > > I'm not sure what that means. What other error-related functions? Look at error_* function in the API (src/emacs_module.h [1]). error_get() lets you get the signal symbol & data. error_check() simply tells you if there was an error and error_clear() clears current error. They will be implemented once we have a safe funcall. The safe funcall() will have a catch-all condition-case and will set a global error state than will be accessible via the API. (Daniel's design) > on error right now"? What means "returns to module code"? "Returns to module code" means when a function (funcall in this case) exits normally via return (no longjmp). Since funcall() is called by modules, when it returns it returns to module code. Hence "returns to module code". > Do you provide "cdr"? no, not directly. You have to intern "cdr" and call funcall(). > If so, what does it do when a module calls it on > a string object? I'd expect it to signal the error and longjmp to the > nearest condition-case that catches it (presumably from outside of the > module code, unless the module code setup condition_case as well). Correct. condition-case is not part of the API though. Like for cdr you have to intern "condition-case", setup the lisp forms as arguments yourself and funcall() it. Haven't tested it yet. > You're talking about how to get docstrings from the source code, but > I think we should expect Emacs to need/fetch them during "load" at which > point we'll be looking at the compiled code. So the first question is > where should those docstrings (regardless of whether they were found and > prepared by make-docfile or by some new tool) be located? Inside the > .so file? Is the source code which should be placed nearby? In some > kind of separate DOC file? Like with my old module branch, I was thinking of having multiple DOC files. When a module is built a DOC file is also generated from the source of the module. When a module is loaded it looks for the module DOC file and uses it. This involves changing the doc field of a symbol from int to Lisp_Object that stores ("path/to/doc" . POSITION), iirc. See previous discussions we had on this. We can always do things differently, its not too late. The pro of docfile is that you can also store the position of the definition in the source code, which is always helpful. > Even without a printer function, I think it makes sense at least to > provide some kind of "type" information so that it's obvious when two > "user objects" are "of the same type". The method table can play the > role of a "type". > > Also, it might make sense to let Emacs build this "method table" object. > So instead of exposing an emacs_user_ptr_ops structure, export > a function which creates a pointer to such an object. This way the > actual emacs_user_ptr_ops structure can more easily evolve, and Emacs > can more easily fill the various slots with default values where Good idea. > applicable (e.g. one slot might point to the module that owns the object > and might better be filled by the Emacs core than by the module itself). Currently each instance of the emacs_env (the struct that holds function pointers to the API that is created upon request from modules) has a unique id used for module identification. That way the module API implementation can know which module is using each API function. 1: https://github.com/aaptel/emacs-dynamic-module/blob/dynamic-modules-2/src/emacs_module.h ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 10:13 ` Aurélien Aptel @ 2015-09-28 21:59 ` Davis Herring 0 siblings, 0 replies; 765+ messages in thread From: Davis Herring @ 2015-09-28 21:59 UTC (permalink / raw) To: Aurélien Aptel Cc: Paul Eggert, Tom Tromey, Emacs development discussions, Philipp Stephani, Stefan Monnier, Daniel Colascione, Stephen Leake > Correct. condition-case is not part of the API though. Like for cdr > you have to intern "condition-case", setup the lisp forms as arguments > yourself and funcall() it. Haven't tested it yet. You can't funcall special forms; thus in part the need for things like internal_condition_case. You'd have to use eval. Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 3:01 ` Stefan Monnier 2015-09-28 10:13 ` Aurélien Aptel @ 2015-09-28 15:57 ` Stephen Leake 1 sibling, 0 replies; 765+ messages in thread From: Stephen Leake @ 2015-09-28 15:57 UTC (permalink / raw) To: emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: >> * pick a new syntax and teach make-docfile how to parse it. This is >> the clean approach IMO, but it requires more work. We can use a >> sufficiently simple syntax so that it can be embedded in comments in >> other languages than C. >> * define DEFVAR/DEFUN macro in module API header file to a noop so >> that make-docfile can parse it as it is. > > You're talking about how to get docstrings from the source code, but > I think we should expect Emacs to need/fetch them during "load" at which > point we'll be looking at the compiled code. So the first question is > where should those docstrings (regardless of whether they were found and > prepared by make-docfile or by some new tool) be located? Inside the > .so file? Is the source code which should be placed nearby? In some > kind of separate DOC file? At one point, we agreed that the module C code doc strings only need to be accessible after the module is loaded. That can be done with a function call in the module initialize function, along with the defun call. In that case, the doc strings are in the .so file. If the module author wants some doc strings to be accessible before load time, they can be on autoloaded functions in elisp code. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-26 14:56 ` Aurélien Aptel 2015-09-28 3:01 ` Stefan Monnier @ 2015-09-28 15:42 ` Philipp Stephani 2015-09-28 16:12 ` Aurélien Aptel 2015-09-28 19:39 ` Stefan Monnier 2015-10-04 4:30 ` Tom Tromey 2 siblings, 2 replies; 765+ messages in thread From: Philipp Stephani @ 2015-09-28 15:42 UTC (permalink / raw) To: Aurélien Aptel, Stefan Monnier Cc: Tom Tromey, Stephen Leake, Daniel Colascione, Emacs development discussions, Paul Eggert [-- Attachment #1: Type: text/plain, Size: 2091 bytes --] Aurélien Aptel <aurelien.aptel+emacs@gmail.com> schrieb am Sa., 26. Sep. 2015 um 16:56 Uhr: > How should module docstring be written? We either: > > * pick a new syntax and teach make-docfile how to parse it. This is > the clean approach IMO, but it requires more work. We can use a > sufficiently simple syntax so that it can be embedded in comments in > other languages than C. > * define DEFVAR/DEFUN macro in module API header file to a noop so > that make-docfile can parse it as it is. > Library headers should respect namespace conventions. Because in C all symbols are global, it's important to pick names that are unlikely to clash. Usually this is done by prefixing all names with a string that is thought to be sufficiently unique, like "emacs" in your case. But DEFVAR/DEFUN don't follow that convention, so they can't be used in the header file. There are some documentation frameworks available, e.g. Doxygen. It might be a good idea to use one of them instead of trying to define your own syntax. > > As for the finalizer, I wanted to add a function in the API: > > /* Finalizer prototype */ > typedef int (*emacs_finalizer_function)(void *ptr); > > emacs_value make_user_ptr (emacs_env *env, > void *ptr, emacs_finalizer_function *fin); > I still don't understand why we need finalizers. Using finalizers in languages without deterministic garbage collection is generally an antipattern. > > > Or we can have a full "method table" with printer function and other > things we might need in the future. Although It's a bit overkill with > just finalizer/printer... > > /* Printer prototype */ > typedef emacs_value (*emacs_printer_function)(void *ptr); > > /* User-ptr operations */ > typedef struct { > emacs_finalizer_function *fin; > emacs_printer_function *print; > /* ... */ > } emacs_user_ptr_ops; > > emacs_value make_user_ptr (emacs_env *env, > void *ptr, emacs_user_ptr_ops *ops); > What is the use case for this? Is the "user_ptr" functionality really needed? [-- Attachment #2: Type: text/html, Size: 2800 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 15:42 ` Philipp Stephani @ 2015-09-28 16:12 ` Aurélien Aptel 2015-09-28 19:39 ` Stefan Monnier 1 sibling, 0 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-09-28 16:12 UTC (permalink / raw) To: Philipp Stephani Cc: Daniel Colascione, Emacs development discussions, Paul Eggert, Stefan Monnier, Tom Tromey, Stephen Leake On Mon, Sep 28, 2015 at 5:42 PM, Philipp Stephani <p.stephani2@gmail.com> wrote: > What is the use case for this? Is the "user_ptr" functionality really > needed? Most libraries creates opaque pointers type you re-use for each calls. See some libarchive samples for example [1] Imagine porting libarchive to emacs as a module. You would use a struct archive pointer stored as a user pointer in an Emacs value. And the new lisp functions would be very similar to the libarchive API i.e. taking the struct archive handle as a parameter. We might not have deteminist finalizer but we could come up with a lisp macro similar to Python 'with' keyword [2] that would set up an unwind-protect that calls the finalizer. 1: https://github.com/libarchive/libarchive/wiki/Examples#List_contents_of_Archive_stored_in_File 2: http://effbot.org/zone/python-with-statement.htm ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 15:42 ` Philipp Stephani 2015-09-28 16:12 ` Aurélien Aptel @ 2015-09-28 19:39 ` Stefan Monnier 2015-09-28 19:41 ` Daniel Colascione 1 sibling, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-09-28 19:39 UTC (permalink / raw) To: Philipp Stephani Cc: Daniel Colascione, Emacs development discussions, Paul Eggert, Aurélien Aptel, Tom Tromey, Stephen Leake > There are some documentation frameworks available, e.g. Doxygen. > It might be a good idea to use one of them instead of trying to define > your own syntax. Using doxygen sounds like a good idea. Since the only thing we really need to formalize is the place and format of the "compiled" docstrings (e.g. "a DOC file"), there could even be several tools available which allow placing the docstring in various ways in the source code. And each module could use the tool it prefers. > I still don't understand why we need finalizers. Using finalizers in > languages without deterministic garbage collection is generally an > antipattern. Maybe that's "generally" the case, but when you need to interface a GC'd language with a manually-managed library, it's the standard technique (and pretty much only/best). The finalizer of course has to be "invisible". Typically, it will do nothing more than call "free" (or something equivalent) on a few objects. > What is the use case for this? Is the "user_ptr" functionality really > needed? Think of a module which tries to provide bignums to Elisp via GMP. It'll need to provide the new "bignum" objects, and they'll be internally represented as GMP objects (which are manually allocated/freed). So it has to define a new Lisp_Object type, and some of its fields are not Lisp_Objects but some pointer to an internal thingy that needs to be freed iff the Lisp_Object is reclaimed. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 19:39 ` Stefan Monnier @ 2015-09-28 19:41 ` Daniel Colascione 2015-09-29 5:04 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-09-28 19:41 UTC (permalink / raw) To: Stefan Monnier, Philipp Stephani Cc: Aurélien Aptel, Stephen Leake, Paul Eggert, Tom Tromey, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 719 bytes --] On 09/28/2015 12:39 PM, Stefan Monnier wrote: >> There are some documentation frameworks available, e.g. Doxygen. >> It might be a good idea to use one of them instead of trying to define >> your own syntax. > > Using doxygen sounds like a good idea. > > Since the only thing we really need to formalize is the place and format > of the "compiled" docstrings (e.g. "a DOC file"), there could even be > several tools available which allow placing the docstring in various > ways in the source code. And each module could use the tool it prefers. Do we even need this optimization in the modern world? Life would be simpler if we could just get rid of the lazy-loaded documentation string machinery. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 19:41 ` Daniel Colascione @ 2015-09-29 5:04 ` Stefan Monnier 0 siblings, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2015-09-29 5:04 UTC (permalink / raw) To: Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Aurélien Aptel, Tom Tromey, Stephen Leake > Do we even need this optimization in the modern world? Life would be > simpler if we could just get rid of the lazy-loaded documentation string > machinery. I don't have an opinion on that. Regardless of whether it's lazy-loaded (from a DOC file or from a special section in the .so file or ...) or not, we need to define specifically where the doc will be found. Maybe if non-lazy-loading is used the doc can be provided in the source code without any special processing. That'd be nice. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-26 14:56 ` Aurélien Aptel 2015-09-28 3:01 ` Stefan Monnier 2015-09-28 15:42 ` Philipp Stephani @ 2015-10-04 4:30 ` Tom Tromey 2015-10-04 14:11 ` Aurélien Aptel 2 siblings, 1 reply; 765+ messages in thread From: Tom Tromey @ 2015-10-04 4:30 UTC (permalink / raw) To: Aurélien Aptel Cc: Paul Eggert, Tom Tromey, Emacs development discussions, Philipp Stephani, Stefan Monnier, Daniel Colascione, Stephen Leake >>>>> "Aurélien" == Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: [ module progress ] Tonight I tried to use the module code to write an FFI module using libffi. I found some holes that make this difficult to do. Aurélien> As for the finalizer, I wanted to add a function in the API: Aurélien> Or we can have a full "method table" with printer function and other Aurélien> things we might need in the future. Although It's a bit overkill with Aurélien> just finalizer/printer... It would be great to be able to make new types from C. That would let me wrap up various C objects I'd like to return opaquely to Lisp. Wrapping pointers would be good enough (for now I am using bit vectors) but having more control would be much better. Overkill here is better. You'll want to extend this vtable over time, for example to add a GC mark function. I don't particularly care if the vtable is exposed or private. Of course, if you can add types from C, why not from Lisp? But I guess I could write a module to allow that :) Here's my list of other things that I noticed. Note that my module isn't working yet, so take it with a grain of salt. * I found the emacs_runtime / emacs_env split strange. I don't know what the purpose of this is. Also there doesn't seem to be a way to free an emacs_env, which I suppose makes sense in a way; though shouldn't they simply be GC'd as well? * module-call never frees "args". * For error handling for now I ended up just calling Emacs stuff directly. Tom ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 4:30 ` Tom Tromey @ 2015-10-04 14:11 ` Aurélien Aptel 2015-10-04 14:22 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-10-04 14:11 UTC (permalink / raw) To: Tom Tromey Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Stefan Monnier, Daniel Colascione, Stephen Leake On Sun, Oct 4, 2015 at 6:30 AM, Tom Tromey <tom@tromey.com> wrote: > Tonight I tried to use the module code to write an FFI module using > libffi. I found some holes that make this difficult to do. Cool :) > It would be great to be able to make new types from C. That would let > me wrap up various C objects I'd like to return opaquely to Lisp. > Wrapping pointers would be good enough (for now I am using bit vectors) > but having more control would be much better. > > Overkill here is better. You'll want to extend this vtable over time, > for example to add a GC mark function. I don't particularly care if the > vtable is exposed or private. > > Of course, if you can add types from C, why not from Lisp? But I guess > I could write a module to allow that :) We have to be careful with this vtable thing. I don't want to end up with C++-level complexity with operator overloading, copy/move constructor, etc. To store pointers you can currently use bit-vectors as you did or also have a table that maps integers to pointers on the module side. For example, a module could return new "types" using a cons ('my-type . ID) where ID is an integer index into a pointer table handled by the module author. It's more work for module writers but it works and keeps the complexity of the module interface low. The only thing we cannot do rigth now is finalizers. But looking through the commits I saw that Daniel added support for "finalizer" in emacs core but I haven't looked into what it actually does. Maybe we can re-use this feature instead of doing it again basically. > * I found the emacs_runtime / emacs_env split strange. I don't know > what the purpose of this is. Also there doesn't seem to be a way to Daniel's design is modeled after the JNI spec where the env must be used from the thread that created the runtime the env came from, IIRC. I have added a "private" module_id field in the env structure which is used to index a module global refs. I was also thinking that you could have for example a module that lets you write sub-modules in python, each with a different module_id but the same runtime. > free an emacs_env, which I suppose makes sense in a way; though > shouldn't they simply be GC'd as well? Nothing can be unloaded in elisp but I didn't made that assumption for modules and I've indexed global refs by module so that you can clear them per module if we ever implement that. > * module-call never frees "args". Fixed, thanks. > * For error handling for now I ended up just calling Emacs stuff > directly. Ok. If you have a public repo somewhere I'd be interested to have a look at your experiements. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 14:11 ` Aurélien Aptel @ 2015-10-04 14:22 ` Aurélien Aptel 0 siblings, 0 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-10-04 14:22 UTC (permalink / raw) To: Tom Tromey Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Stefan Monnier, Daniel Colascione, Stephen Leake On Sun, Oct 4, 2015 at 4:11 PM, Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: > We have to be careful with this vtable thing. I don't want to end up > with C++-level complexity with operator overloading, copy/move ><snip> > module side. For example, a module could return new "types" using a > cons ('my-type . ID) where ID is an integer index into a pointer table > handled by the module author. It's more work for module writers but it > works and keeps the complexity of the module interface low. To be clear, I still prefer the opaque pointer type with the vtable thingy solution. I was just showing alternatives. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-24 12:45 ` Aurélien Aptel 2015-09-24 13:58 ` Stefan Monnier @ 2015-09-28 15:35 ` Philipp Stephani 2015-09-28 17:04 ` Philipp Stephani ` (2 more replies) 1 sibling, 3 replies; 765+ messages in thread From: Philipp Stephani @ 2015-09-28 15:35 UTC (permalink / raw) To: Aurélien Aptel, Stefan Monnier Cc: Tom Tromey, Stephen Leake, Daniel Colascione, Emacs development discussions, Paul Eggert [-- Attachment #1: Type: text/plain, Size: 2006 bytes --] Aurélien Aptel <aurelien.aptel+emacs@gmail.com> schrieb am Do., 24. Sep. 2015 um 14:45 Uhr: > Some updates. > > I haven't made any progress on errors. I was reading on > condition-case, setjmp/longjmp and how it's used for > signaling/throwing. I actually knew very little about it. I shouldnt > be the one writing this stuff I think... Anyway I was looking into how > I would set up a "catch-all" wrapping code so that we can implement a > funcall that always returns and I still haven't figured it out. I have implemented this in a private fork: https://github.com/phst/emacs-dynamic-module/commit/b14073ef8a522bdb90a8d7f0edc575edfd75da26 Note that code is only a suggestion how it could be implemented. It deviates from Daniel's design by using return parameters instead of TLS, but that's only a minor difference. The important part is the addition of protected_call_n to eval.c. > And realisticly if we > want this in emacs 25 it's the only way (I don't feel confident enough > to do that bit properly and I'm the only one working on this). I feel relatively strongly about this, so I'd work on implementing this if you'd like. > We can > always fix it afterwards or simply have a "safe" and an "unsafe" > version of funcall in the API. Going from the safe to the unsafe direction is easy if it's really required, but going the other direction is hard. I'd suggest to only implement the safe version for now and only add the unsafe version if there's some data that shows it's required. > I think changing the API in the early stage is fine and I don't worry > too much about binary API changes because it's only going to be used > with GPL plugins (i.e. modules can be fixed and recompiled, most of > the time). > > True, however once there's an API it's a good idea to keep it stable. I expect people to start writing modules relatively soon once the interface is available, so it's better to put a bit more effort into the interface. [-- Attachment #2: Type: text/html, Size: 2953 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 15:35 ` Philipp Stephani @ 2015-09-28 17:04 ` Philipp Stephani 2015-09-28 19:30 ` Stefan Monnier 2015-10-04 13:25 ` Aurélien Aptel 2 siblings, 0 replies; 765+ messages in thread From: Philipp Stephani @ 2015-09-28 17:04 UTC (permalink / raw) To: Aurélien Aptel, Stefan Monnier Cc: Tom Tromey, Stephen Leake, Daniel Colascione, Emacs development discussions, Paul Eggert [-- Attachment #1: Type: text/plain, Size: 1337 bytes --] Philipp Stephani <p.stephani2@gmail.com> schrieb am Mo., 28. Sep. 2015 um 17:35 Uhr: > Aurélien Aptel <aurelien.aptel+emacs@gmail.com> schrieb am Do., 24. Sep. > 2015 um 14:45 Uhr: > >> Some updates. >> >> I haven't made any progress on errors. I was reading on >> condition-case, setjmp/longjmp and how it's used for >> signaling/throwing. I actually knew very little about it. I shouldnt >> be the one writing this stuff I think... Anyway I was looking into how >> I would set up a "catch-all" wrapping code so that we can implement a >> funcall that always returns and I still haven't figured it out. > > > I have implemented this in a private fork: > https://github.com/phst/emacs-dynamic-module/commit/b14073ef8a522bdb90a8d7f0edc575edfd75da26 > Note that code is only a suggestion how it could be implemented. It > deviates from Daniel's design by using return parameters instead of TLS, > but that's only a minor difference. The important part is the addition of > protected_call_n to eval.c. > Here's a more minimal implementation using TLS (but we only have one thread, the thread checking needs to be implemented as well, but that's unrelated): https://github.com/phst/emacs-dynamic-module/commit/41a8cb8a1d29346331fcaf1f28b6c5bee8c8f6ad This is less than minimal because throw isn't dealt with. [-- Attachment #2: Type: text/html, Size: 2219 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 15:35 ` Philipp Stephani 2015-09-28 17:04 ` Philipp Stephani @ 2015-09-28 19:30 ` Stefan Monnier 2015-10-04 13:25 ` Aurélien Aptel 2 siblings, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2015-09-28 19:30 UTC (permalink / raw) To: Philipp Stephani Cc: Daniel Colascione, Emacs development discussions, Paul Eggert, Aurélien Aptel, Tom Tromey, Stephen Leake > Going from the safe to the unsafe direction is easy if it's really > required, but going the other direction is hard. You have it backward: it's easy to add a wrapper that catches signals, but it's *impossible* to "uncatch" a signal that was caught (you can at best re-throw that signal, which is a close-enough approximation in many cases, but is still not the same). > I'd suggest to only implement the safe version for now and only add > the unsafe version if there's some data that shows it's required. The only version that is required is the one that lets signals walk up the stack freely. I'm not opposed to also providing a "safe" version that catches signals and turns them into something else, but the other one is indispensable. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 15:35 ` Philipp Stephani 2015-09-28 17:04 ` Philipp Stephani 2015-09-28 19:30 ` Stefan Monnier @ 2015-10-04 13:25 ` Aurélien Aptel 2015-10-04 14:38 ` Philipp Stephani 2 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-10-04 13:25 UTC (permalink / raw) To: Philipp Stephani Cc: Paul Eggert, Daniel Colascione, Emacs development discussions, Stefan Monnier, Tom Tromey, Stephen Leake First of all thank you for actually contributing with code, Philip. Very much appreciated. On Mon, Sep 28, 2015 at 5:35 PM, Philipp Stephani <p.stephani2@gmail.com> wrote: > I have implemented this in a private fork: > https://github.com/phst/emacs-dynamic-module/commit/b14073ef8a522bdb90a8d7f0edc575edfd75da26 > Note that code is only a suggestion how it could be implemented. It deviates > from Daniel's design by using return parameters instead of TLS, but that's > only a minor difference. The important part is the addition of > protected_call_n to eval.c. I've looked at both branch. The one using an in-out return parameter looks really annoying to use though. I think I prefer the "minimal" implementation [1]. Using that version, we could add an unsafe_funcall() to the API that doesnt do any signal checking so that we have both. Stefan, is this enough? Or should we actually expose `condition-case' for finer-grained control? 1: https://github.com/phst/emacs-dynamic-module/commit/41a8cb8a1d29346331fcaf1f28b6c5bee8c8f6ad ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 13:25 ` Aurélien Aptel @ 2015-10-04 14:38 ` Philipp Stephani 0 siblings, 0 replies; 765+ messages in thread From: Philipp Stephani @ 2015-10-04 14:38 UTC (permalink / raw) To: Aurélien Aptel Cc: Paul Eggert, Daniel Colascione, Emacs development discussions, Stefan Monnier, Tom Tromey, Stephen Leake [-- Attachment #1: Type: text/plain, Size: 1394 bytes --] Aurélien Aptel <aurelien.aptel+emacs@gmail.com> schrieb am So., 4. Okt. 2015 um 15:25 Uhr: > First of all thank you for actually contributing with code, Philip. > Very much appreciated. > > On Mon, Sep 28, 2015 at 5:35 PM, Philipp Stephani <p.stephani2@gmail.com> > wrote: > > I have implemented this in a private fork: > > > https://github.com/phst/emacs-dynamic-module/commit/b14073ef8a522bdb90a8d7f0edc575edfd75da26 > > Note that code is only a suggestion how it could be implemented. It > deviates > > from Daniel's design by using return parameters instead of TLS, but > that's > > only a minor difference. The important part is the addition of > > protected_call_n to eval.c. > > I've looked at both branch. The one using an in-out return parameter > looks really annoying to use though. I think I prefer the "minimal" > implementation [1]. That's fine, it's Daniel's design, after all, and using TLS for error reporting is common (e.g. errno). I've added a pull request for this: https://github.com/aaptel/emacs-dynamic-module/pull/7 Another pull request implements checking whether calls are only made on the main thread: https://github.com/aaptel/emacs-dynamic-module/pull/8 > Using that version, we could add an > unsafe_funcall() to the API that doesnt do any signal checking so that > we have both. > Daniel, what do you think about that? [-- Attachment #2: Type: text/html, Size: 2239 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-15 0:55 ` Stefan Monnier 2015-09-15 1:06 ` Daniel Colascione 2015-09-24 12:45 ` Aurélien Aptel @ 2015-09-28 15:25 ` Philipp Stephani 2015-09-28 19:26 ` Stefan Monnier 2015-09-28 19:28 ` Daniel Colascione 2 siblings, 2 replies; 765+ messages in thread From: Philipp Stephani @ 2015-09-28 15:25 UTC (permalink / raw) To: Stefan Monnier, Daniel Colascione Cc: Aurélien Aptel, Stephen Leake, Paul Eggert, Tom Tromey, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 493 bytes --] Stefan Monnier <monnier@iro.umontreal.ca> schrieb am Di., 15. Sep. 2015 um 02:55 Uhr: > Just, FWIW we can keep talking about it, but my opinion is quite firmly > made. I want the first API to provide access to the "naked" primitives > with no condition-case wrapping. > > This is wrong and dangerous. It makes dynamic loading far less useful than it could be. Essentially modules e.g. written in C++ will have to consist of a small C shim that makes IPC calls to some out-of-process server. [-- Attachment #2: Type: text/html, Size: 793 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 15:25 ` Philipp Stephani @ 2015-09-28 19:26 ` Stefan Monnier 2015-09-28 19:31 ` Daniel Colascione 2015-09-28 19:28 ` Daniel Colascione 1 sibling, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-09-28 19:26 UTC (permalink / raw) To: Philipp Stephani Cc: Daniel Colascione, Emacs development discussions, Paul Eggert, Aurélien Aptel, Tom Tromey, Stephen Leake > This is wrong and dangerous. It makes dynamic loading far less useful than > it could be. Essentially modules e.g. written in C++ will have to consist > of a small C shim that makes IPC calls to some out-of-process server. That is again nonsense: what is being requested (i.e. avoid non-local exits) can be performed on top of the API I advocte, just as efficiently as if it were done "natively" inside that API. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 19:26 ` Stefan Monnier @ 2015-09-28 19:31 ` Daniel Colascione 0 siblings, 0 replies; 765+ messages in thread From: Daniel Colascione @ 2015-09-28 19:31 UTC (permalink / raw) To: Stefan Monnier, Philipp Stephani Cc: Aurélien Aptel, Stephen Leake, Paul Eggert, Tom Tromey, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 662 bytes --] On 09/28/2015 12:26 PM, Stefan Monnier wrote: >> This is wrong and dangerous. It makes dynamic loading far less useful than >> it could be. Essentially modules e.g. written in C++ will have to consist >> of a small C shim that makes IPC calls to some out-of-process server. > > That is again nonsense: what is being requested (i.e. avoid non-local > exits) can be performed on top of the API I advocte, just as efficiently > as if it were done "natively" inside that API. That's true, but only intuitively true for people with a great deal of experience with finicky C code. I still think you're ignoring human factors in making this decision. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 15:25 ` Philipp Stephani 2015-09-28 19:26 ` Stefan Monnier @ 2015-09-28 19:28 ` Daniel Colascione 2015-09-28 20:09 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-09-28 19:28 UTC (permalink / raw) To: Philipp Stephani, Stefan Monnier Cc: Aurélien Aptel, Stephen Leake, Paul Eggert, Tom Tromey, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 1228 bytes --] On 09/28/2015 08:25 AM, Philipp Stephani wrote: > > > Stefan Monnier <monnier@iro.umontreal.ca > <mailto:monnier@iro.umontreal.ca>> schrieb am Di., 15. Sep. 2015 um > 02:55 Uhr: > > Just, FWIW we can keep talking about it, but my opinion is quite firmly > made. I want the first API to provide access to the "naked" primitives > with no condition-case wrapping. > > > This is wrong and dangerous. It makes dynamic loading far less useful > than it could be. Essentially modules e.g. written in C++ will have to > consist of a small C shim that makes IPC calls to some out-of-process > server. While I agree that making non-local exits part of the public API is a titanic footgun and a mistake we'll regret for decades, it's not the case that it forces non-C modules to use IPC shims. Emacs non-local unwinding stops at the first matching condition_case on the stack, so as long there's a condition-case frame between a stack frame that can't be unwound with longjmp (say, one with C++ destructors) and the Emacs core, the program will work correctly if Emacs longjmps. Non-local returns are awful, yes, but they do not make it impossible to integrate non-C languages with Emacs. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 19:28 ` Daniel Colascione @ 2015-09-28 20:09 ` Philipp Stephani 2015-09-28 20:10 ` Daniel Colascione 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-09-28 20:09 UTC (permalink / raw) To: Daniel Colascione, Stefan Monnier Cc: Aurélien Aptel, Stephen Leake, Paul Eggert, Tom Tromey, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 1700 bytes --] Daniel Colascione <dancol@dancol.org> schrieb am Mo., 28. Sep. 2015 um 21:29 Uhr: > On 09/28/2015 08:25 AM, Philipp Stephani wrote: > > > > > > Stefan Monnier <monnier@iro.umontreal.ca > > <mailto:monnier@iro.umontreal.ca>> schrieb am Di., 15. Sep. 2015 um > > 02:55 Uhr: > > > > Just, FWIW we can keep talking about it, but my opinion is quite > firmly > > made. I want the first API to provide access to the "naked" > primitives > > with no condition-case wrapping. > > > > > > This is wrong and dangerous. It makes dynamic loading far less useful > > than it could be. Essentially modules e.g. written in C++ will have to > > consist of a small C shim that makes IPC calls to some out-of-process > > server. > > While I agree that making non-local exits part of the public API is a > titanic footgun and a mistake we'll regret for decades, it's not the > case that it forces non-C modules to use IPC shims. Emacs non-local > unwinding stops at the first matching condition_case on the stack, so as > long there's a condition-case frame between a stack frame that can't be > unwound with longjmp (say, one with C++ destructors) and the Emacs core, > the program will work correctly if Emacs longjmps. > The issue is that it's impossible for module authors to write such a `condition-case' in the general case. While individual signals can be caught, it's not possible to catch all signals using the condition-case Lisp function. Similarly, there is no way to write a `catch' block that would catch all tags; `catch' only allows catching individual tag symbols. > > Non-local returns are awful, yes, but they do not make it impossible to > integrate non-C languages with Emacs. > > [-- Attachment #2: Type: text/html, Size: 2412 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 20:09 ` Philipp Stephani @ 2015-09-28 20:10 ` Daniel Colascione 2015-09-29 5:00 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-09-28 20:10 UTC (permalink / raw) To: Philipp Stephani, Stefan Monnier Cc: Aurélien Aptel, Stephen Leake, Paul Eggert, Tom Tromey, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 531 bytes --] On 09/28/2015 01:09 PM, Philipp Stephani wrote: > The issue is that it's impossible for module authors to write such a > `condition-case' in the general case. While individual signals can be > caught, it's not possible to catch all signals using the condition-case > Lisp function. Similarly, there is no way to write a `catch' block that > would catch all tags; `catch' only allows catching individual tag symbols. I believe Stefan is proposing adding a true catch-all to the module API, like internal_condition_case. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 20:10 ` Daniel Colascione @ 2015-09-29 5:00 ` Stefan Monnier 0 siblings, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2015-09-29 5:00 UTC (permalink / raw) To: Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Aurélien Aptel, Tom Tromey, Stephen Leake > I believe Stefan is proposing adding a true catch-all to the module API, > like internal_condition_case. Right. And/or a "safe_funcall" (which does both the catching and the funcall). Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 15:14 ` Daniel Colascione 2015-09-14 17:48 ` Stefan Monnier @ 2015-09-15 2:56 ` Stephen J. Turnbull 2015-09-15 3:00 ` Daniel Colascione 2015-09-15 7:45 ` Michael Albinus 1 sibling, 2 replies; 765+ messages in thread From: Stephen J. Turnbull @ 2015-09-15 2:56 UTC (permalink / raw) To: Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Tom Tromey, Stephen Leake Daniel Colascione writes: > Calls back to Emacs functions will be fairly common, because > modules use these functions to manipulate Emacs data on behalf of > their own callers. Real examples, please. S?XEmacs has two decades of experience with wrapping random libraries, Emacs has some too, and there just aren't any that I can think of offhand. I see no reason why modules in Emacs will change that pattern; S?XEmacs has a 1.5 decades of experience with require'able modules, and it hasn't changed there. > Who will be common, because the entire point of writing modules is > to work with the _non_-Emacs world. I can imagine one module that > has both non-trivial calls back into Emacs and quite a bit of > internal state in suitable for management with Emacs > primitives. It's called Python. You have a serious licensing problem, I think, which is one of the important reasons why we haven't seen very much in the way of complex integration in the past. But be that as it may.... You're kidding, right? I can't imagine that somebody with the skills in both Python and Emacs and the energy and time needed to write the kind of deep integration you're talking about would be deterred by the need to adapt a couple score lines of "suggested code" to their preferred conception of error handling. Of course it will be hard to write the boilerplate the first time, but by the same token the first try will undoubtedly suck. So the implementation will *change* to fix the suckiness. If the boilerplate is embedded in the module API it will likely force the modules to update to work with the new rules. I think a module that seems to be working well is very unlikely to be pleased by such churn. So, you could be right in the long run, but I think it's the better part of valor to not restrict modules in that way now. Instead, put the responsibility for error handling the callback itself first. Modules that want to can provide their own child-proof wrappers. After experience incorporate the best (plural, if appropriate) of those wrappers in Emacs itself, either embedded in the module API or as an optional standard wrapper. > safe_call blindly suppresses errors. Errors from module-invoked > functions to propagate normally from the perspective of surrounding > Lisp code. Show us the code to "propagate errors normally to surrounding Lisp code". XEmacs has its own safe_call-type functions that do somewhat better than merely suppressing all errors, but they're heavy and hard to use correctly -- and there we know at least that the calling side of the call is XEmacs (the other side is typically low-level I/O code that uses Lisp to format output or parse input). But for modules, since callbacks can be anything and the callback will be separated from the "surrounding Lisp code" by arbitrary amounts of non-Lisp code doing unknown things, I doubt you can do "normal". But let's see how close you can get. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-15 2:56 ` Stephen J. Turnbull @ 2015-09-15 3:00 ` Daniel Colascione 2015-09-15 8:16 ` Stephen J. Turnbull 2015-09-15 7:45 ` Michael Albinus 1 sibling, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-09-15 3:00 UTC (permalink / raw) To: Stephen J. Turnbull Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Tom Tromey, Stephen Leake [-- Attachment #1: Type: text/plain, Size: 444 bytes --] On 09/14/2015 07:56 PM, Stephen J. Turnbull wrote: > Daniel Colascione writes: > > primitives. It's called Python. > > You have a serious licensing problem, I think, which is one of the > important reasons why we haven't seen very much in the way of complex > integration in the past. The rest of the discussion aside: Python's current license is GPLv3-compatible, isn't it? gnu.org and Python's documentation both claim it is. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-15 3:00 ` Daniel Colascione @ 2015-09-15 8:16 ` Stephen J. Turnbull 2015-09-15 8:45 ` David Kastrup 0 siblings, 1 reply; 765+ messages in thread From: Stephen J. Turnbull @ 2015-09-15 8:16 UTC (permalink / raw) To: Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Tom Tromey, Stephen Leake Daniel Colascione writes: > On 09/14/2015 07:56 PM, Stephen J. Turnbull wrote: > The rest of the discussion aside: Python's current license is > GPLv3-compatible, isn't it? gnu.org and Python's documentation both > claim it is. AFAIK IANAL TINLA. That's not the issue I have in mind. Pragmatically speaking, even if it's not possible to legally prohibit you from distributing such a module, I think Richard would veto incorporation of such a module in Emacs, because it would make it possible to silently link Emacs to proprietary code via a Python plugin. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-15 8:16 ` Stephen J. Turnbull @ 2015-09-15 8:45 ` David Kastrup 2015-09-15 13:18 ` Daniel Colascione 0 siblings, 1 reply; 765+ messages in thread From: David Kastrup @ 2015-09-15 8:45 UTC (permalink / raw) To: Stephen J. Turnbull Cc: Paul Eggert, Tom Tromey, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Daniel Colascione, Stephen Leake "Stephen J. Turnbull" <stephen@xemacs.org> writes: > Daniel Colascione writes: > > On 09/14/2015 07:56 PM, Stephen J. Turnbull wrote: > > > The rest of the discussion aside: Python's current license is > > GPLv3-compatible, isn't it? gnu.org and Python's documentation both > > claim it is. > > AFAIK IANAL TINLA. That's not the issue I have in mind. > > Pragmatically speaking, even if it's not possible to legally prohibit > you from distributing such a module, I think Richard would veto > incorporation of such a module in Emacs, because it would make it > possible to silently link Emacs to proprietary code via a Python > plugin. Well, regarding the "proprietary plugin" issue it would seem most expedient to have the plugins run in the Emacs GC and exception model and, where third-party independently developed libraries are to be integrated, to have to compile/byte-compile/assemble some library-specific wrapper encapsulating/mapping the exceptions/callbacks to the Emacs model. I have no idea regarding the technical feasibility of various different approaches. But regarding the "circumvent GPLv3" angle, having a default model of completely separate exception/memory handling and FFI that allows a drop-in direct binary use of libraries not specifically developed for use with Emacs, while certainly offering the maximum of convenience in one regard, forms a reasonably clearly defined license barrier for "application as a whole" forming a clear stop for the reach of the GPLv3. So having our binary interfaces and calling conventions and memory/exception handling default to "like Emacs does" is not just Lisp-friendly but is also keeping our license enforcement options more conservative. While my personal opinion is that licensing considerations should not justify complications amounting to uselessness, I see nothing wrong with letting them serve as tie-breaker. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-15 8:45 ` David Kastrup @ 2015-09-15 13:18 ` Daniel Colascione 2015-09-15 13:33 ` David Kastrup 2015-09-15 16:11 ` Stephen J. Turnbull 0 siblings, 2 replies; 765+ messages in thread From: Daniel Colascione @ 2015-09-15 13:18 UTC (permalink / raw) To: David Kastrup, Stephen J. Turnbull Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Tom Tromey, Stephen Leake [-- Attachment #1: Type: text/plain, Size: 1082 bytes --] On 09/15/2015 01:45 AM, David Kastrup wrote: > So having our binary interfaces and calling conventions and > memory/exception handling default to "like Emacs does" is not just > Lisp-friendly but is also keeping our license enforcement options more > conservative. I don't see how. Once we have a module that allows general-purpose loading of code not intended for use in Emacs (no matter how hard that initial module is to write), there will be literally nothing preventing users making arbitrary GPLv3-compatible modules that allow users to chain-load non-GPLv3-compatible code. There's no way to require that everything in the Emacs address space be licensed under the GPL. And that's a good thing, because equating sharing an address space with a "derivative work" boundary is ridiculous. Even if Emacs were to look for some I_LOAD_ONLY_GPLV3=1 export from loaded modules, the GPL does not prohibit a module simply lying. The GPLv3 does not require the implementation of technical license enforcement mechanisms. (If it did, it would violate freedom 0.) [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-15 13:18 ` Daniel Colascione @ 2015-09-15 13:33 ` David Kastrup 2015-09-15 13:39 ` Daniel Colascione 2015-09-15 16:11 ` Stephen J. Turnbull 1 sibling, 1 reply; 765+ messages in thread From: David Kastrup @ 2015-09-15 13:33 UTC (permalink / raw) To: Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Stephen J. Turnbull, Tom Tromey, Stephen Leake Daniel Colascione <dancol@dancol.org> writes: > On 09/15/2015 01:45 AM, David Kastrup wrote: >> So having our binary interfaces and calling conventions and >> memory/exception handling default to "like Emacs does" is not just >> Lisp-friendly but is also keeping our license enforcement options more >> conservative. > > I don't see how. Maybe you should have read more than a single paragraph then. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-15 13:33 ` David Kastrup @ 2015-09-15 13:39 ` Daniel Colascione 2015-09-15 13:43 ` David Kastrup 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-09-15 13:39 UTC (permalink / raw) To: David Kastrup Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Stephen J. Turnbull, Tom Tromey, Stephen Leake [-- Attachment #1: Type: text/plain, Size: 575 bytes --] On 09/15/2015 06:33 AM, David Kastrup wrote: > Daniel Colascione <dancol@dancol.org> writes: > >> On 09/15/2015 01:45 AM, David Kastrup wrote: >>> So having our binary interfaces and calling conventions and >>> memory/exception handling default to "like Emacs does" is not just >>> Lisp-friendly but is also keeping our license enforcement options more >>> conservative. >> >> I don't see how. > > Maybe you should have read more than a single paragraph then. Maybe you shouldn't snip the part where I explain how the rest of your argument is incorrect. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-15 13:39 ` Daniel Colascione @ 2015-09-15 13:43 ` David Kastrup 0 siblings, 0 replies; 765+ messages in thread From: David Kastrup @ 2015-09-15 13:43 UTC (permalink / raw) To: Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Stephen J. Turnbull, Tom Tromey, Stephen Leake Daniel Colascione <dancol@dancol.org> writes: > On 09/15/2015 06:33 AM, David Kastrup wrote: >> Daniel Colascione <dancol@dancol.org> writes: >> >>> On 09/15/2015 01:45 AM, David Kastrup wrote: >>>> So having our binary interfaces and calling conventions and >>>> memory/exception handling default to "like Emacs does" is not just >>>> Lisp-friendly but is also keeping our license enforcement options more >>>> conservative. >>> >>> I don't see how. >> >> Maybe you should have read more than a single paragraph then. > > Maybe you shouldn't snip the part where I explain how the rest of your > argument is incorrect. Your "explanation" did not fit the "rest of my argument" and discussed a different scenario. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-15 13:18 ` Daniel Colascione 2015-09-15 13:33 ` David Kastrup @ 2015-09-15 16:11 ` Stephen J. Turnbull 1 sibling, 0 replies; 765+ messages in thread From: Stephen J. Turnbull @ 2015-09-15 16:11 UTC (permalink / raw) To: Daniel Colascione; +Cc: Emacs development discussions Daniel Colascione writes: > There's no way to require that everything in the Emacs address > space be licensed under the GPL. That is true (for example, the data segment is not covered by Emacs's GPL unless it contains Emacs code), but it's a useful guide to reasoning about code. > And that's a good thing, because equating sharing an address space > with a "derivative work" boundary is ridiculous. I'm pretty sure Richard doesn't consider it "ridiculous", though I expect he'd prefer a phrase like "as a first approximation" to "equate". > Even if Emacs were to look for some I_LOAD_ONLY_GPLV3=1 export from > loaded modules, the GPL does not prohibit a module simply lying. The GPL doesn't prohibit any behavior of software. However, it arguably would prohibit distribution of a module that lies in that way. Not because of the falsehood of the lie, but because from the fact of the lie I deduce the module actually violates the terms of the GPL by creating a derivative work, not all of which is licensed under the GPL. (I understand you disagree with that argument in principle. I'm just saying that it can be argued, and I expect it *would* be argued by the FSF, all the way to court if necessary.) ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-15 2:56 ` Stephen J. Turnbull 2015-09-15 3:00 ` Daniel Colascione @ 2015-09-15 7:45 ` Michael Albinus 1 sibling, 0 replies; 765+ messages in thread From: Michael Albinus @ 2015-09-15 7:45 UTC (permalink / raw) To: Stephen J. Turnbull Cc: Paul Eggert, Tom Tromey, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Daniel Colascione, Stephen Leake "Stephen J. Turnbull" <stephen@xemacs.org> writes: > > Calls back to Emacs functions will be fairly common, because > > modules use these functions to manipulate Emacs data on behalf of > > their own callers. > > Real examples, please. S?XEmacs has two decades of experience with > wrapping random libraries, Emacs has some too, and there just aren't > any that I can think of offhand. I see no reason why modules in Emacs > will change that pattern; S?XEmacs has a 1.5 decades of experience > with require'able modules, and it hasn't changed there. For the records, years ago I had ported Emacs' dbusbind.c to SXEmacs, using their ffi interface. It was almost running; I forgot why it wasn't finished and included in SXEmacs. A corner-case problem with events maybe. Once Emacs' dynamic modules are usable, I plan to write a scuccessor of dbusbind.c for kdbus as dynamic module. The D-Bus machinery is based on (Lisp level) callbacks. Best regards, Michael. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 1:58 ` Stefan Monnier 2015-09-14 2:08 ` Daniel Colascione @ 2015-09-28 15:12 ` Philipp Stephani 2015-09-28 19:20 ` Stefan Monnier 1 sibling, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-09-28 15:12 UTC (permalink / raw) To: Stefan Monnier, Daniel Colascione Cc: Aurélien Aptel, Tom Tromey, Paul Eggert, Stephen Leake, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 1707 bytes --] Stefan Monnier <monnier@iro.umontreal.ca> schrieb am Mo., 14. Sep. 2015 um 03:58 Uhr: > >>> It's not possible to skip frames in module code using longjmp, so > >> Why not? > > Because most C code isn't expecting to be unwound. > > Forcing non-local flow control on module code is completely > > unacceptable. Emacs needs to return with an error indication set. > > Hmm... I'm still not sure what's the issue. > > AFAICT, the only odd case I can think of is the following: > > 1- Emacs calls some module code via the new API. > 2- This code (which is Emacs-specific) will know about Fthrow. > Even if it knows about non-local jumps, in many cases it can't do anything about them except wrapping them. For example, longjmp is illegal in most C++ programs (and probably in most other languages as well). > 3- It may call some non-Emacs-specific code from some other library. 4- This non-Emacs-specific code calls back to some Emacs-specific > function. > Step 3 and 4 can be left out. The issue only requires that the plugin contains some code that is not suited for longjmp; e.g., all C++ code, no matter whether written specifically for Emacs or not. > 5- This Emacs-specific function calls Fthrow/Fsignal. > > Where the problem only shows if/when we reach point 5. > > This problem can be handled between 4 and 5 by using an appropriate > internal_condition_case. > Partially yes. internal_condition_case with a Qt handler can indeed catch all signals, but this invocation is only possible from Emacs C code (using internal_condition_case), and the fact that signal and throw use longjmp is an implementation detail anyway, so the catch-all code needs to be inside the module code. [-- Attachment #2: Type: text/html, Size: 2510 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 15:12 ` Philipp Stephani @ 2015-09-28 19:20 ` Stefan Monnier 0 siblings, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2015-09-28 19:20 UTC (permalink / raw) To: Philipp Stephani Cc: Paul Eggert, Tom Tromey, Emacs development discussions, Aurélien Aptel, Daniel Colascione, Stephen Leake >> 1- Emacs calls some module code via the new API. >> 2- This code (which is Emacs-specific) will know about Fthrow. > Even if it knows about non-local jumps, in many cases it can't do anything > about them except wrapping them. There's nothing else none can ever do about them other than wrapping them. So the fact that they can only wrap them is not a downside of some alternative. > For example, longjmp is illegal in most C++ programs (and probably in > most other languages as well). Most Emacs modules will be written in C, methinks. For those written in other languages, since the API is expressed in C, they'll have to accommodate the interaction with this C API, yes. If they want to add a whole layer that wraps every function call in an internal_condition_case, that's fine by me. > The issue only requires that the plugin contains some code that is not > suited for longjmp; e.g., all C++ code, no matter whether written > specifically for Emacs or not. That's a problem for the C++ code, not for Emacs's C-level module API. > Partially yes. internal_condition_case with a Qt handler can indeed catch > all signals, but this invocation is only possible from Emacs C code (using > internal_condition_case), Clearly, we'll want to export it to the modules as well. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-13 20:33 ` Daniel Colascione 2015-09-14 1:58 ` Stefan Monnier @ 2015-09-14 3:43 ` Stephen J. Turnbull 2015-09-14 3:54 ` Daniel Colascione 2015-09-28 15:19 ` Philipp Stephani 1 sibling, 2 replies; 765+ messages in thread From: Stephen J. Turnbull @ 2015-09-14 3:43 UTC (permalink / raw) To: Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Tom Tromey, Stephen Leake Daniel Colascione writes: > On 09/13/2015 01:31 PM, Stefan Monnier wrote: > >> It's not possible to skip frames in module code using longjmp, so > > > > Why not? > > Because most C code isn't expecting to be unwound. Forcing non-local > flow control on module code is completely unacceptable. "Completely unacceptable" is nonsense. Module code needs to be written the same way any other Emacs code is written, using various unwind-protect constructs. If the module wraps external code that has state that persists past the unwinding, you also need to use the underlying code's own "unwind protection". For example, XEmacs has had a PostgreSQL interface module based on libpq for about 15 years, and nobody has ever reported any trouble of that kind. The Lisp API provides transactions, and the unwind code in XEmacs knows to rollback if there's a pending transaction on nonlocal exit. Sure, all of XEmacs, PostgreSQL, and the module have had bugs in them -- but nobody has blamed an XEmacs crash or database corruption on that module yet. OK, there may not be all that much experience, but at least two people used it heavily in mission critical roles for 5 years (they were supporting a Fortune 500 company's trouble ticket database). I acknowledge that the risk is probably somewhat greater than if the code were built-in to XEmacs. Sure, it's likely that module programmers will not be as well-versed in Emacs unwinding as Emacs core developers are, but by that same token they're probably quite well-versed in the target code's features. Overall, modules are likely to be less stable than core Emacs, but presumably that's a tradeoff that module users are willing to accept. And I'm sure that there's non-robust code in libraries out there that will be totally horked on a non-local exit. But AFAICS you have the same problem there if you link statically or at Emacs initialization -- that code just shouldn't be linked into Emacs period. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 3:43 ` Stephen J. Turnbull @ 2015-09-14 3:54 ` Daniel Colascione 2015-09-14 4:24 ` Stefan Monnier 2015-09-14 7:27 ` Stephen J. Turnbull 2015-09-28 15:19 ` Philipp Stephani 1 sibling, 2 replies; 765+ messages in thread From: Daniel Colascione @ 2015-09-14 3:54 UTC (permalink / raw) To: Stephen J. Turnbull Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Tom Tromey, Stephen Leake [-- Attachment #1: Type: text/plain, Size: 1712 bytes --] On 09/13/2015 08:43 PM, Stephen J. Turnbull wrote: > Daniel Colascione writes: > > On 09/13/2015 01:31 PM, Stefan Monnier wrote: > > > >> It's not possible to skip frames in module code using longjmp, so > > > > > > Why not? > > > > Because most C code isn't expecting to be unwound. Forcing non-local > > flow control on module code is completely unacceptable. > > "Completely unacceptable" is nonsense. Module code needs to be > written the same way any other Emacs code is written, using various > unwind-protect constructs. Why? There is no positive reason to make Emacs module code resemble Emacs core code. In fact, there's a strong reason to make Emacs module code more conventional, because it'll improve the accessibility of the API, which in turn will increase the quantity and quality of Emacs modules. The Emacs core code has a lot of baggage. It's not practical to clean it up today, but the module system is a greenfield project. There is no reason to burden it the same way. > If the module wraps external code that > has state that persists past the unwinding, you also need to use the > underlying code's own "unwind protection". We shouldn't break this perfectly reasonable code: void foo() { std::string x = something(); emacs_bar(x.c_str()); } longjmp()ing out of emacs_bar prevents any stack unwinding happening, which means that any code that requires stack unwinding for correctness needs to swap every Emacs API call in the equivalent of condition-case. It's cumbersome, especially for any binding that isn't pure C. Can you name an extension system for any other program that longjmps out of its public API functions? [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 3:54 ` Daniel Colascione @ 2015-09-14 4:24 ` Stefan Monnier 2015-09-28 15:21 ` Philipp Stephani 2015-09-14 7:27 ` Stephen J. Turnbull 1 sibling, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-09-14 4:24 UTC (permalink / raw) To: Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Stephen J. Turnbull, Aurélien Aptel, Tom Tromey, Stephen Leake > Why? There is no positive reason to make Emacs module code resemble > Emacs core code. Of course, there is. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 4:24 ` Stefan Monnier @ 2015-09-28 15:21 ` Philipp Stephani 2015-09-28 19:23 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-09-28 15:21 UTC (permalink / raw) To: Stefan Monnier, Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Stephen J. Turnbull, Aurélien Aptel, Tom Tromey, Stephen Leake [-- Attachment #1: Type: text/plain, Size: 521 bytes --] Stefan Monnier <monnier@iro.umontreal.ca> schrieb am Mo., 14. Sep. 2015 um 06:24 Uhr: > > Why? There is no positive reason to make Emacs module code resemble > > Emacs core code. > > Of course, there is. > > > Which one? Given the overall state of the Emacs core code (lots of global mutable state, thread-hostile, lots of macros...) I'd rather want modules to be as different from the Emacs core as possible. The module interface is an interface. No good interface prescribes how its implementations have to look like. [-- Attachment #2: Type: text/html, Size: 838 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 15:21 ` Philipp Stephani @ 2015-09-28 19:23 ` Stefan Monnier 0 siblings, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2015-09-28 19:23 UTC (permalink / raw) To: Philipp Stephani Cc: Tom Tromey, Emacs development discussions, Paul Eggert, Stephen J. Turnbull, Aurélien Aptel, Daniel Colascione, Stephen Leake > Which one? Given the overall state of the Emacs core code (lots of global > mutable state, thread-hostile, lots of macros...) I'd rather want modules > to be as different from the Emacs core as possible. > The module interface is an interface. No good interface prescribes how its > implementations have to look like. The interface just says "funcall may exit non-locally". It doesn't have to say that it uses longjmp for that. But the end result is the same: if you want to write your module in a language other than C, you'll have to deal with interactions between C (including longjmp) and that other language. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 3:54 ` Daniel Colascione 2015-09-14 4:24 ` Stefan Monnier @ 2015-09-14 7:27 ` Stephen J. Turnbull 2015-09-14 14:45 ` Stephen Leake 1 sibling, 1 reply; 765+ messages in thread From: Stephen J. Turnbull @ 2015-09-14 7:27 UTC (permalink / raw) To: Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Tom Tromey, Stephen Leake Daniel Colascione writes: > On 09/13/2015 08:43 PM, Stephen J. Turnbull wrote: > > Daniel Colascione writes: > > > On 09/13/2015 01:31 PM, Stefan Monnier wrote: > > > > > >> It's not possible to skip frames in module code using longjmp, so > > > > > > > > Why not? > > > > > > Because most C code isn't expecting to be unwound. Forcing non-local > > > flow control on module code is completely unacceptable. > > > > "Completely unacceptable" is nonsense. Module code needs to be > > written the same way any other Emacs code is written, using various > > unwind-protect constructs. > > Why? There is no positive reason to make Emacs module code resemble > Emacs core code. Er, because it *is* Emacs code? If a function in a module simply wraps a library call, then you need to use that library's facilities to handle problems. But if it manipulates any Emacs data using Emacs APIs, you'll use Emacs facilities to handle all that ugly stuff like GC and Fsignal. > In fact, there's a strong reason to make Emacs module code more > conventional, because it'll improve the accessibility of the API, > which in turn will increase the quantity and quality of Emacs > modules. I think that's wishful thinking. In my experience with the XEmacs module code, what basically happens most of the time is that you write some Lisp to beat the data into the right structure, then you write a little bit of C to marshal Lisp primitive types into the underlying library's format, then you call the library API, and marshal the return into Lisp data types. Often it's more convenient to call the Lisp APIs from C than to return to Lisp and do it there, but it's equivalent. Sure, there's a lot of boring boilerplate, but it ain't rocket science by that very token. In the relatively rare case that you have a way of passing a callback into Lisp to the library, you either program very defensively in the Lisp, or just wrap the whole thing in a condition-case (such as ignore-errors) before passing it to the library. > The Emacs core code has a lot of baggage. It's not practical to > clean it up today, but the module system is a greenfield > project. There is no reason to burden it the same way. AFAICS, no, it's not a greenfield project. It's a second story on the same foundations. You're welcome to prove otherwise, but I don't have a clue how you propose to do it (without disallowing callbacks into Lisp entirely, and I don't see how you can enforce that without some very pervasive nannying code). > Can you name an extension system for any other program that > longjmps out of its public API functions? No, not with any confidence. XEmacs is the only program whose internal implementation of nonlocal exit I know well. But I would guess that if the language implements nonlocal exits, then any callback that can be an arbitrary function in the language can longjmp. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 7:27 ` Stephen J. Turnbull @ 2015-09-14 14:45 ` Stephen Leake 2015-09-15 1:46 ` Stephen J. Turnbull 0 siblings, 1 reply; 765+ messages in thread From: Stephen Leake @ 2015-09-14 14:45 UTC (permalink / raw) To: emacs-devel "Stephen J. Turnbull" <stephen@xemacs.org> writes: > Daniel Colascione writes: > > On 09/13/2015 08:43 PM, Stephen J. Turnbull wrote: > > > Daniel Colascione writes: > > > > On 09/13/2015 01:31 PM, Stefan Monnier wrote: > > > > > > > >> It's not possible to skip frames in module code using longjmp, so > > > > > > > > > > Why not? > > > > > > > > Because most C code isn't expecting to be unwound. Forcing non-local > > > > flow control on module code is completely unacceptable. > > > > > > "Completely unacceptable" is nonsense. Module code needs to be > > > written the same way any other Emacs code is written, using various > > > unwind-protect constructs. > > > > Why? There is no positive reason to make Emacs module code resemble > > Emacs core code. > > Er, because it *is* Emacs code? That was my initial view as well, because I new I needed fast performance for my particular use case. But I suspect some (most?) modules will be added just to provide a lisp interface to some external library; the authors will see that as part of their lisp code, not part of Emacs core. One reason Emacs succeeds is because lisp is so forgiving; module developers will expect the Emacs module API to be similarly forgiving. I don't think we need to accept that as a hard requirement, but anything we can do towards that goal that has reasonable performance penalties could be a win. > > In fact, there's a strong reason to make Emacs module code more > > conventional, because it'll improve the accessibility of the API, > > which in turn will increase the quantity and quality of Emacs > > modules. > > I think that's wishful thinking. In my experience with the XEmacs > module code, what basically happens most of the time is that you write > some Lisp to beat the data into the right structure, then you write a > little bit of C to marshal Lisp primitive types into the underlying > library's format, then you call the library API, and marshal the > return into Lisp data types. Often it's more convenient to call the > Lisp APIs from C than to return to Lisp and do it there, but it's > equivalent. Sure, there's a lot of boring boilerplate, but it ain't > rocket science by that very token. I see that as "conventional code"; you certainly didn't mention callbacks and longjmp here. > In the relatively rare case that you have a way of passing a callback > into Lisp to the library, you either program very defensively in the > Lisp, Always a good idea anyway, at least until thorough testing is done. > or just wrap the whole thing in a condition-case (such as > ignore-errors) before passing it to the library. What is the downside of having the Emacs module API do that for you? -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 14:45 ` Stephen Leake @ 2015-09-15 1:46 ` Stephen J. Turnbull 0 siblings, 0 replies; 765+ messages in thread From: Stephen J. Turnbull @ 2015-09-15 1:46 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel Stephen Leake writes: > > Er, because it *is* Emacs code? > > That was my initial view as well, because I new I needed fast > performance for my particular use case. > > But I suspect some (most?) modules will be added just to provide a lisp > interface to some external library; the authors will see that as part of > their lisp code, not part of Emacs core. Which is what I described and you called "conventional". But that's *not* what Daniel is exercised about. > One reason Emacs succeeds is because lisp is so forgiving; module > developers will expect the Emacs module API to be similarly > forgiving. Yeah, and they expect a pony too. The module API will be C, which is not a forgiving language. Lisp forgiveness is possible because it's backed up by the use of longjmp, you know. > > In the relatively rare case that you have a way of passing a callback > > into Lisp to the library, you either program very defensively in the > > Lisp, > > Always a good idea anyway, at least until thorough testing is done. > > > or just wrap the whole thing in a condition-case (such as > > ignore-errors) before passing it to the library. > > What is the downside of having the Emacs module API do that for you? Well, the very existence of `ignore-errors' is an abomination, you can hardly expect me to condone its automatic use. :-) Suppressing errors screws exactly the non-Emacsy developers it's supposed to help -- the callback code is nearly impossible to debug without the Emacs expertise that we're assuming the module developer *doesn't have*. Also, the expense of an unnecessary condition-case in a tight loop is not to be ignored, when the Lisp-level "no brain required" safety belt for code that might signal but isn't performance-critical is so simple and stylized. But in most modules, we're just using library code to do a calculation, and then we can pass the result (including signaling an error status) back out to Lisp. XEmacs (and even more so SXEmacs) have been doing this a lot over the years. The necessary code is pretty boring, and I've never seen one that involves the nonlocal exit issue. The Lisp APIs that are most frequently used are hard to reduce (DEFUN, DEFVAR). GCPROs (S?XEmacs still uses them) are very rare, and even those can generally be avoided by sticking strictly to the marshalling/unmarshalling in C, and doing Lisp manipulations in Lisp. The problem that Daniel is worried about is real, but I don't see a good way of solving it in Emacs. In any case, it doesn't matter to encouraging use of modules. The vast majority of modules simply won't have callbacks to deal with. People who *want* to write a callback in Lisp and pass it to C are going to be rare, and likely to be experienced Emacs developers, I would think. If not, they're surely multilingual. They probably can deal with it. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-14 3:43 ` Stephen J. Turnbull 2015-09-14 3:54 ` Daniel Colascione @ 2015-09-28 15:19 ` Philipp Stephani 2015-09-29 1:55 ` Stephen J. Turnbull 1 sibling, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-09-28 15:19 UTC (permalink / raw) To: Stephen J. Turnbull, Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Stefan Monnier, Aurélien Aptel, Tom Tromey, Stephen Leake [-- Attachment #1: Type: text/plain, Size: 1597 bytes --] Stephen J. Turnbull <turnbull@sk.tsukuba.ac.jp> schrieb am Mo., 14. Sep. 2015 um 05:43 Uhr: > Daniel Colascione writes: > > On 09/13/2015 01:31 PM, Stefan Monnier wrote: > > > >> It's not possible to skip frames in module code using longjmp, so > > > > > > Why not? > > > > Because most C code isn't expecting to be unwound. Forcing non-local > > flow control on module code is completely unacceptable. > > "Completely unacceptable" is nonsense. Module code needs to be > written the same way any other Emacs code is written, Why? The module interface defines an interface, not an implementation strategy. The observable behavior of Emacs is described in the Emacs manual, and that contains nothing about longjmp (unsurprisingly, given that it's an implementation detail). > using various > unwind-protect constructs. It is not possible to write such constructs in general. Stack frames that don't originate from C programs simply can't be part of a non-local jump. unwind-protect doesn't help at all because it doesn't stop non-local jumps. > > > And I'm sure that there's non-robust code in libraries out there that > will be totally horked on a non-local exit. But AFAICS you have the > same problem there if you link statically or at Emacs initialization > -- that code just shouldn't be linked into Emacs period. > > > Such a decision would massively reduce the usefulness of modules. It would prevent dynamic modules in any language other than C, and even for C modules implementors would need to be careful not to write longjmp-hosting code. This is indeed unacceptable. [-- Attachment #2: Type: text/html, Size: 2441 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-28 15:19 ` Philipp Stephani @ 2015-09-29 1:55 ` Stephen J. Turnbull 2015-09-29 9:11 ` David Kastrup 2015-09-29 21:04 ` Davis Herring 0 siblings, 2 replies; 765+ messages in thread From: Stephen J. Turnbull @ 2015-09-29 1:55 UTC (permalink / raw) To: Philipp Stephani Cc: Tom Tromey, Emacs development discussions, Paul Eggert, Stefan Monnier, Aurélien Aptel, Daniel Colascione, Stephen Leake Philipp Stephani writes: > > using various unwind-protect constructs. > > It is not possible to write such constructs in general. Stack > frames that don't originate from C programs simply can't be part of > a non-local jump. unwind-protect doesn't help at all because it > doesn't stop non-local jumps. Er, what does "stop non-local jumps"? What Emacs can do is catch its own non-local jumps so as not to orphan non-Emacs stack frames. It can't catch (or prevent!) anybody else's. > > And I'm sure that there's non-robust code in libraries out there > > that will be totally horked on a non-local exit. But AFAICS you > > have the same problem there if you link statically or at Emacs > > initialization -- that code just shouldn't be linked into Emacs > > period. > Such a decision would massively reduce the usefulness of > modules. I don't see how. Please explain which use cases you have in mind. > It would prevent dynamic modules in any language other > than C, Why? There's a long history of embedding other languages in Emacs (CCL, perlmacs, pymacs). Runtime optional loading aka dynamic modules involves problems new to GNU Emacs, but the longjmp problem is not new. It just wasn't a problem in practice because those called languages don't provide a callback interface (as implemented in those projects). They were used purely as subroutines to Emacs: call in, get result or error, forget until next time. No longjmps to Emacs out of the embedded interpreter. > and even for C modules implementors would need to be careful not to > write longjmp-hosting code. This is indeed unacceptable. Heh. The GPL and RMS's historic no-dynamic-modules policy are each far more restrictive of code you might want to link with Emacs, yet you accept them. Politics aside, I wish you luck (and backups, early and often) when using code that longjmps past Emacs stack frames, such as any embedded language that implements its own exception handling. You'll need it. But that's not what is at issue here. What is at issue is how to handle the case where the module calls into foreign code and provides a callback that calls Lisp, and thus might do [main Lisp] -> [module] -> [callback Lisp] --Fsignal--> [main Lisp] leaving the module in an inconsistent state because its stack has been blown away. As far as I can see, this is a very rare case, limited to (eg) embedding another full-blown interpreter in Emacs. Modules like libz, libcanna, and libpq (in XEmacs) simply don't provide callbacks, so this scenario is impossible. OTOH, somebody who really wants to provide more access to Python internals than `comint' does is not going to need or want Fcondition_case_for_dummies. The way I propose to handle the issue is by providing a sample wrapper based on condition-case for Lisp callbacks that handles longjmps out of Fsignal (which I hope is the only way to longjmp in Emacs). Thus: +-----------Fsignal-----------+ | | V | [main Lisp] -> [module] -> [condition-case] -> [callback Lisp] -+ A | A | A | | | | | | | +--return---+ +------------+ +-------normal return--------+ protecting the module. I don't see what else can possibly work, since if you set a condition case in the API calling into the module (ie, in [main Lisp]), you've already hosed the called code by the time you handle it. I don't see how a *generic* (and mandatory, per Daniel's proposal) wrapper can be provided, since the callback API will be defined by the called code, not by Emacs. The sample wrapper is likely to be quite generic, however, as many typical callbacks are going to reduce to Fapply(lisp_code, lisp_data). But it can't be fully generic. Some callback APIs are going to supply module-defined data structures and perhaps a different number of arguments, and in those cases you'll need to write your own callback wrapper that marshalls the arguments into Lisp. Finally, you may anticipate that certain kinds of errors will be common in the Lisp code called, and you would like to handle those in your own way. A generic wrapper provided by the module API is either going to provide only a generic "you are hosed" error return, or it's going to have to reimplement condition-case. Why not just use Fcondition_case itself? And, of course, some users may prefer to write their own condition-case in Lisp. Bottom line on a mandatory API enforcing a condition-case: Mostly YAGNI, most of the rest YCUIWYNI[1]. Footnotes: [1] You Can't Use It Where You Need It. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-29 1:55 ` Stephen J. Turnbull @ 2015-09-29 9:11 ` David Kastrup 2015-09-30 6:06 ` Stephen J. Turnbull 2015-09-29 21:04 ` Davis Herring 1 sibling, 1 reply; 765+ messages in thread From: David Kastrup @ 2015-09-29 9:11 UTC (permalink / raw) To: Stephen J. Turnbull Cc: Paul Eggert, Daniel Colascione, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Tom Tromey, Stephen Leake "Stephen J. Turnbull" <stephen@xemacs.org> writes: > Philipp Stephani writes: > > > > using various unwind-protect constructs. > > > > It is not possible to write such constructs in general. Stack > > frames that don't originate from C programs simply can't be part of > > a non-local jump. unwind-protect doesn't help at all because it > > doesn't stop non-local jumps. > > Er, what does "stop non-local jumps"? What Emacs can do is catch its > own non-local jumps so as not to orphan non-Emacs stack frames. It > can't catch (or prevent!) anybody else's. Oh, it could provide its own versions of setjmp/longjmp overriding the C library ones. That would actually put the hooks into quite a few non-local jump implementations. The downside being that Emacs would need to provide binary-compatible setjmp/longjmp implementations for all platforms it supports. Or some trickery for getting at the library ones without others seeing them. And nobody else trying similar trickery. So while it stinks like trouble all over, "can't" is too strong a qualifier. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-29 9:11 ` David Kastrup @ 2015-09-30 6:06 ` Stephen J. Turnbull 2015-09-30 6:24 ` David Kastrup 0 siblings, 1 reply; 765+ messages in thread From: Stephen J. Turnbull @ 2015-09-30 6:06 UTC (permalink / raw) To: David Kastrup Cc: Paul Eggert, Tom Tromey, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Daniel Colascione, Stephen Leake David Kastrup writes: > "Stephen J. Turnbull" <stephen@xemacs.org> writes: > > Er, what does "stop non-local jumps"? What Emacs can do is catch its > > own non-local jumps so as not to orphan non-Emacs stack frames. It > > can't catch (or prevent!) anybody else's. [Dubious :-) proof-of-concept which likely fails in some important case or other omitted.] > So while it stinks like trouble all over, "can't" is too strong a > qualifier. What was that you were saying to Paul about arguing the wrong side of your own point? As usual, we are in violent agreement. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-30 6:06 ` Stephen J. Turnbull @ 2015-09-30 6:24 ` David Kastrup 0 siblings, 0 replies; 765+ messages in thread From: David Kastrup @ 2015-09-30 6:24 UTC (permalink / raw) To: Stephen J. Turnbull Cc: Paul Eggert, Tom Tromey, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Daniel Colascione, Stephen Leake "Stephen J. Turnbull" <stephen@xemacs.org> writes: > David Kastrup writes: > > "Stephen J. Turnbull" <stephen@xemacs.org> writes: > > > > Er, what does "stop non-local jumps"? What Emacs can do is catch its > > > own non-local jumps so as not to orphan non-Emacs stack frames. It > > > can't catch (or prevent!) anybody else's. > > [Dubious :-) proof-of-concept which likely fails in some important > case or other omitted.] > > > So while it stinks like trouble all over, "can't" is too strong a > > qualifier. > > What was that you were saying to Paul about arguing the wrong side of > your own point? As usual, we are in violent agreement. Not really I think. Conservative garbage collection stinks like trouble all over as well and Emacs does it. It's sort of like the Sherlock Holmes principle. Once you've ruled out all the possibilities that don't stink, it has to be one of the stinky ones. So the decisive factor is not whether a solution stinks or not, but whether there is already one that stinks less and will work. I don't see we are there yet. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-29 1:55 ` Stephen J. Turnbull 2015-09-29 9:11 ` David Kastrup @ 2015-09-29 21:04 ` Davis Herring 2015-09-30 6:07 ` Stephen J. Turnbull 1 sibling, 1 reply; 765+ messages in thread From: Davis Herring @ 2015-09-29 21:04 UTC (permalink / raw) To: Stephen J. Turnbull Cc: Paul Eggert, Daniel Colascione, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Tom Tromey, Stephen Leake > I don't see what else can possibly work, since if you set a condition > case in the API calling into the module (ie, in [main Lisp]), you've > already hosed the called code by the time you handle it. What if we avoid the longjmp call rather than catching it? Define a (thread-local) signal-raising hook which is also a specpdl barrier. A C++ client, for example, could write (perhaps with some added 'extern "C"') namespace { struct emacs_exception : std::exception { emacs_exception(emacs_value e,emacs_value d) : error(e),data(d) {} emacs_value error,data; }; void die(emacs_value error,emacs_value data) { throw emacs_exception(error,data); } emacs_value my_subr(emacs_env *env,int nargs,emacs_value args[]) { env->error_handle(env,die); // creates barrier try { std::vector</*...*/> data; // to be cleaned up env->funcall(env,/*...*/); } catch(const emacs_exception &e) { // various variables assumed to be already obtained elsewhere if(eq(e.error,Qfile_error)) { /* handle file-not-found */; return Qnil; } else env->error_signal(env,e.error,e.data); } return Qt; } } Then Fsignal/Fthrow can do its cleanup down to the barrier, then call the hook. The exception unwinds the stack back into the C++ module, does appropriate destructor things, and then is caught before the module returns to Emacs. There, the module can choose to return normally (thus acting like condition-case) or propagate the error (thus having its destructors act like unwind-protect). Here we have the overhead of error_handle only once per call from Emacs into the module rather than on each call from the module into Emacs (probably larger). We might be able to avoid even that by putting the handler into the emacs_env, but that would lose the flexible barrier placement and presumably Fsignal still has to consult a how-to-signal variable that would have to be set at least once per Emacs->module call. Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-29 21:04 ` Davis Herring @ 2015-09-30 6:07 ` Stephen J. Turnbull 2015-09-30 6:56 ` Herring, Davis 0 siblings, 1 reply; 765+ messages in thread From: Stephen J. Turnbull @ 2015-09-30 6:07 UTC (permalink / raw) To: Davis Herring Cc: Paul Eggert, Daniel Colascione, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Tom Tromey, Stephen Leake Davis Herring writes: > What if we avoid the longjmp call rather than catching it? Define a > (thread-local) signal-raising hook which is also a specpdl barrier. We still have to catch the longjmp. The setjmp *is* the barrier as far as Fsignal and Fthrow are concerned. See unwind_to_catch(). Unless you're proposing to replace unwind_to_catch itself with something that signals "locally" for the duration of the callback. That seems like a very dubious idea to me. Rather, as Daniel has been at pains to say, it's a shame Emacs didn't do that in the first place, as more recently designed languages have managed to do.[1] So if we're going to provide a "no nonlocal exit" unwind_to_catch() for modules, let's use it for Emacs itself, too! > A C++ client, for example, could write AIUI, that's exactly what Daniel and Philipp *don't* want! They want to avoid having the client contain error handling code for Lisp at all, instead managing it behind the API in the Emacs module implementation, and thus making it idiot-proof. Perhaps with some concessions for setting handlers to the DIYers, but there would alway be a safety net. I think this is an illusion, and a dangerous one, for code that is complicated enough to provide a callback interface that accepts Lisp functions. *Especially* if written in crash-prone languages like C and C++. > We might be able to avoid even that by putting the handler into the > emacs_env, Which is what Daniel and Philipp want, and which is what I think is a horrible idea, akin to using `ignore-errors' in basic Lisp functions like `car'. Footnotes: [1] Amusingly enough, even those languages don't always manage to avoid longjmp entirely: Python 3.5 still has two instances of longjmp, one in Modules/fpectlmodule.c, and the other in Modules/readline.c. ^ permalink raw reply [flat|nested] 765+ messages in thread
* RE: Dynamic loading progress 2015-09-30 6:07 ` Stephen J. Turnbull @ 2015-09-30 6:56 ` Herring, Davis 2015-09-30 7:26 ` Daniel Colascione 2015-09-30 17:16 ` Stephen J. Turnbull 0 siblings, 2 replies; 765+ messages in thread From: Herring, Davis @ 2015-09-30 6:56 UTC (permalink / raw) To: Stephen J. Turnbull Cc: Paul Eggert, Daniel Colascione, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Tom Tromey, Stephen Leake > We still have to catch the longjmp. The setjmp *is* the barrier as > far as Fsignal and Fthrow are concerned. See unwind_to_catch(). The "struct handler" is the barrier: it's a detail of the current implementation that it contains a jmp_buf (that is always used). > Unless you're proposing to replace unwind_to_catch itself with > something that signals "locally" for the duration of the callback. I think by "locally" you mean "by normal function returns only". That's not my idea, which is basically to (conditionally) replace sys_longjmp (catch->jmp, 1); with catch->hook (); where (according to my straw-man code) catch->hook was populated by the call to env->error_handle. It's still a non-local transfer, as is necessary for the existing calls to unwind_to_catch to possibly work. > AIUI, that's exactly what Daniel and Philipp *don't* want! They want > to avoid having the client contain error handling code for Lisp at > all, instead managing it behind the API in the Emacs module > implementation, and thus making it idiot-proof. I'm aiming more for idiot-resistant, without the complexity (and overhead) of wrapping every call into Emacs to protect the caller. In other words, it's a way to recover control (like they want) without significantly extending the "unsafe" interface (which Stefan wants). > Which is what Daniel and Philipp want, and which is what I think is a > horrible idea, akin to using `ignore-errors' in basic Lisp functions > like `car'. But it's not ignore-errors: in my example, the error does propagate, but as a C++ exception rather than a longjmp. Some easy RAII would let you reliably get the error_handle and the matching error_unhandle in one shot (avoiding the possibility of forgetting it, as I did in my example!). In the trivial case that you just want destructors to be called and the error to propagate back into Lisp, you could avoid an explicit try-catch on each module entry point with a wrapper function template. Davis ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-30 6:56 ` Herring, Davis @ 2015-09-30 7:26 ` Daniel Colascione 2015-09-30 8:52 ` Stefan Monnier 2015-09-30 17:16 ` Stephen J. Turnbull 1 sibling, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-09-30 7:26 UTC (permalink / raw) To: Herring, Davis, Stephen J. Turnbull Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Tom Tromey, Stephen Leake [-- Attachment #1: Type: text/plain, Size: 2767 bytes --] On 09/29/2015 11:56 PM, Herring, Davis wrote: >> We still have to catch the longjmp. The setjmp *is* the barrier as >> far as Fsignal and Fthrow are concerned. See unwind_to_catch(). > > The "struct handler" is the barrier: it's a detail of the current implementation that it contains a jmp_buf (that is always used). > >> Unless you're proposing to replace unwind_to_catch itself with >> something that signals "locally" for the duration of the callback. > > I think by "locally" you mean "by normal function returns only". That's not my idea, which is basically to (conditionally) replace > sys_longjmp (catch->jmp, 1); > with > catch->hook (); > > where (according to my straw-man code) catch->hook was populated by the call to env->error_handle. It's still a non-local transfer, as is necessary for the existing calls to unwind_to_catch to possibly work. > >> AIUI, that's exactly what Daniel and Philipp *don't* want! They want >> to avoid having the client contain error handling code for Lisp at >> all, instead managing it behind the API in the Emacs module >> implementation, and thus making it idiot-proof. > > I'm aiming more for idiot-resistant, without the complexity (and overhead) of wrapping every call into Emacs to protect the caller. In other words, it's a way to recover control (like they want) without significantly extending the "unsafe" interface (which Stefan wants). > >> Which is what Daniel and Philipp want, and which is what I think is a >> horrible idea, akin to using `ignore-errors' in basic Lisp functions >> like `car'. > > But it's not ignore-errors: in my example, the error does propagate, > but as a C++ exception rather than a longjmp. Some easy RAII would > let you reliably get the error_handle and the matching error_unhandle > in one shot (avoiding the possibility of forgetting it, as I did in > my example!). In the trivial case that you just want destructors to > be called and the error to propagate back into Lisp, you could avoid > an explicit try-catch on each module entry point with a wrapper > function template. One practical difficulty of this scheme is that we would have to build Emacs itself with exception unwind information. (Since the default Itanium ABI behavior is to abort if we try to unwind through a stack frame for which we don't have unwind information.) I don't think that would be easy to pull off in the general case, and I don't think it's possible in advance to predict what information we might need to allow stack unwinding to proceed. This scheme leads us further into ABI-dependence. I'd prefer longjmp to a system that required us to let C++ exceptions (with what libstdc++?) propagate through arbitrary Emacs frames. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-30 7:26 ` Daniel Colascione @ 2015-09-30 8:52 ` Stefan Monnier 2015-10-04 8:34 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-09-30 8:52 UTC (permalink / raw) To: Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Philipp Stephani, Aurélien Aptel, Stephen J. Turnbull, Tom Tromey, Stephen Leake BTW, all this discussion about C++ modules seems to miss the point: Emacs's own API will be a C API. When you want to use it from a C++ module, you'll have to convert it to a C++ API. At that point, you have various options: - do a minimalist binding which keeps using naked longjmp, and just let the C++ code use explicit internal_condition_case wrappers where it thinks it's needed. - do an "idiot-proof" binding which only provides a "safe_funcall" which catches longjmps and turns them into local exits. - do an "idiot-resistant" binding which only provides a "safe_funcall" that catches longjmps and turns them into C++ exceptions, and then back into Elisp longjmps (and back-and-forth ad nauseum if needed when doing nested mutual callbacks). - ...younameit... I'm fine with any of those things, and AFAIK they can all be done on top of the plain C API with the usual non-local exits. All I care about at this point is the plain C API. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-30 8:52 ` Stefan Monnier @ 2015-10-04 8:34 ` Philipp Stephani 2015-10-04 17:24 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-10-04 8:34 UTC (permalink / raw) To: Stefan Monnier, Daniel Colascione Cc: Paul Eggert, Emacs development discussions, Aurélien Aptel, Stephen J. Turnbull, Tom Tromey, Stephen Leake [-- Attachment #1: Type: text/plain, Size: 2439 bytes --] Stefan Monnier <monnier@iro.umontreal.ca> schrieb am Mi., 30. Sep. 2015 um 10:52 Uhr: > BTW, all this discussion about C++ modules seems to miss the point: > Emacs's own API will be a C API. When you want to use it from a C++ > module, you'll have to convert it to a C++ API. True, and I think nobody expects otherwise. However, as with other interfaces, the Emacs module interface should use not all of C, but the intersection of C and C++ (which is pretty large compared to full C). > At that point, you > have various options: > > - do a minimalist binding which keeps using naked longjmp, and just > let the C++ code use explicit internal_condition_case wrappers where > it thinks it's needed. > This is currently impossible because the necessary code is not available to module authors (and partially does not even exist, as in the case of catch). > - do an "idiot-proof" binding which only provides a "safe_funcall" which > catches longjmps and turns them into local exits. > This is what Daniel and I prefer, however I'd like to avoid the negative spin of the word "idiot" here. To use the first option, a module author has to know all of the following: - that Emacs uses longjmp for non-local exits in Lisp (currently an implementation detail_; - that longjmp is in general unsafe in C++ code; - which subset exactly of C++ is safe for longjmp; - how to correctly set up the necessary traps to reliably catch all longjmps. I think it's a stretch to call everyone who doesn't know all of these things an "idiot". Implementing this option is relatively straightforward; implementing the first option makes it much harder for module authors, with negligible benefit to the Emacs core. > - do an "idiot-resistant" binding which only provides a "safe_funcall" that > catches longjmps and turns them into C++ exceptions, and then back > into Elisp longjmps (and back-and-forth ad nauseum if needed when > doing nested mutual callbacks). > No, this is what a C++ binding to the module interface would have to provide. > I'm fine with any of those things, and AFAIK they can all be done on top > of the plain C API with the usual non-local exits. > All I care about at this point is the plain C API. > > Daniel has designed a great API in https://lists.gnu.org/archive/html/emacs-devel/2015-02/msg00960.html. Let's just implement this API as designed and check later if there's any need for the other options. [-- Attachment #2: Type: text/html, Size: 3598 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 8:34 ` Philipp Stephani @ 2015-10-04 17:24 ` Stefan Monnier 0 siblings, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2015-10-04 17:24 UTC (permalink / raw) To: Philipp Stephani Cc: Paul Eggert, Tom Tromey, Emacs development discussions, Aurélien Aptel, Stephen J. Turnbull, Daniel Colascione, Stephen Leake > True, and I think nobody expects otherwise. However, as with other > interfaces, the Emacs module interface should use not all of C, but the > intersection of C and C++ (which is pretty large compared to full C). That would be desirable, but less so than the fact that the API just exposes the functionality provided by Emacs's core code. So as long as Emacs's signaling facility uses longjmp, that's going to be exposed in the core API. >> - do a minimalist binding which keeps using naked longjmp, and just >> let the C++ code use explicit internal_condition_case wrappers where >> it thinks it's needed. > This is currently impossible because the necessary code is not available to > module authors (and partially does not even exist, as in the case of catch). Irrelevant detail: we're talking about design of some upcoming API, which will require coding. Some of that coding may involve writing new core code, of course. Of course, by that measure, some of that coding could involve replacing longjmp with some other mechanism. My gut feeling is that this would be a very large undertaking and that the result would probably not be palatable to the vast majority of Emacs's C contributors, so I won't hold my breath. > Daniel has designed a great API in > https://lists.gnu.org/archive/html/emacs-devel/2015-02/msg00960.html. Let's > just implement this API as designed and check later if there's any need for > the other options. If you want: Modules can call Lisp functions using `funcall', which does the obvious thing. If Lisp signals or throws, `funcall' returns NULL. that's OK, but it should then be called `safe_funcall', and we should provide another `funcall' which does not catch the error. And if `safe_funcall' cannot be defined "by hand" in a module using other API methods, that would mean that the API is still lacking functionality (e.e. lacking condition_case and things like that). You're not going to convince me otherwise. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* RE: Dynamic loading progress 2015-09-30 6:56 ` Herring, Davis 2015-09-30 7:26 ` Daniel Colascione @ 2015-09-30 17:16 ` Stephen J. Turnbull 2015-09-30 17:32 ` Davis Herring 1 sibling, 1 reply; 765+ messages in thread From: Stephen J. Turnbull @ 2015-09-30 17:16 UTC (permalink / raw) To: Herring, Davis Cc: Paul Eggert, Daniel Colascione, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Tom Tromey, Stephen Leake Herring, Davis writes: > > We still have to catch the longjmp. The setjmp *is* the barrier > > as far as Fsignal and Fthrow are concerned. See > > unwind_to_catch(). > > The "struct handler" is the barrier: it's a detail of the current > implementation that it contains a jmp_buf (that is always used). > where (according to my straw-man code) catch->hook was populated by > the call to env->error_handle. It's still a non-local transfer, as > is necessary for the existing calls to unwind_to_catch to possibly > work. So what's the advantage over unwind_to_catch as implemented? You still need to put the barrier in place, only now you're using mixed idioms (Lisp for the pitcher, C++ for the catcher). That kind of thing always gives me hives. > > Which [...] is what I think is a horrible idea, akin to using > > `ignore-errors' in basic Lisp functions like `car'. > > But it's not ignore-errors: in my example, A-ah, that's *your* example. I was referring to what I believe Daniel and Philipp want, which was the idea you pretty much dismissed as "[too] inflexible": a handler hidden behind the API. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-30 17:16 ` Stephen J. Turnbull @ 2015-09-30 17:32 ` Davis Herring 0 siblings, 0 replies; 765+ messages in thread From: Davis Herring @ 2015-09-30 17:32 UTC (permalink / raw) To: Stephen J. Turnbull Cc: Paul Eggert, Daniel Colascione, Emacs development discussions, Philipp Stephani, Stefan Monnier, Aurélien Aptel, Tom Tromey, Stephen Leake > So what's the advantage over unwind_to_catch as implemented? You > still need to put the barrier in place, only now you're using mixed > idioms (Lisp for the pitcher, C++ for the catcher). That kind of > thing always gives me hives. As I think I said, it lets you avoid reinstalling the handler every time you call into Emacs (and thus having to wrap every Emacs API function). > > But it's not ignore-errors: in my example, > > A-ah, that's *your* example. I was referring to what I believe Daniel > and Philipp want, which was the idea you pretty much dismissed as > "[too] inflexible": a handler hidden behind the API. (I'm still talking about my example here, but only because it serves to demonstrate what properties a hidden handler might have. Another implementation of hidden handlers could of course behave differently, but I haven't seen any particular implementation firmly chosen.) Even if the handler is hidden, the signal isn't swallowed (or even turned into a famously-easy-to-ignore return code): it's turned into an exception and thrown. It's up to the module code what to do about it, as always. My follow-on template-wrapper idea didn't squelch exceptions either, but turned them back into propagating Lisp signals after having run whatever C++ destructors. The inflexible part of the automatic/hidden handler, as I saw it, is that every entry point must perform the try/catch even if it has no destructors to run because Emacs will cause the exception to be thrown anytime control is within the module. It also prevents doing any preparatory work before installing the handler, or making a dynamic choice of handler -- but for neither of those do I have a use case at the moment. Davis -- This product is sold by volume, not by mass. If it appears too dense or too sparse, it is because mass-energy conversion has occurred during shipping. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-04 22:39 ` Daniel Colascione 2015-03-05 13:12 ` Aurélien Aptel @ 2015-03-05 13:17 ` Aurélien Aptel 2015-03-06 5:14 ` Stefan Monnier 2 siblings, 0 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-03-05 13:17 UTC (permalink / raw) To: Daniel Colascione Cc: Eli Zaretskii, Stephen Leake, Stefan Monnier, Emacs development discussions On Wed, Mar 4, 2015 at 11:39 PM, Daniel Colascione <dancol@dancol.org> wrote: > As I'm imagining the system, no. Access is indirected. That insulates C > code from Emacs GC requirements and lets us easily support global > references. Can you explain how global/local references work in your design? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-04 22:39 ` Daniel Colascione 2015-03-05 13:12 ` Aurélien Aptel 2015-03-05 13:17 ` Aurélien Aptel @ 2015-03-06 5:14 ` Stefan Monnier 2015-03-06 18:22 ` Daniel Colascione 2 siblings, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-03-06 5:14 UTC (permalink / raw) To: Daniel Colascione Cc: Aurélien Aptel, Eli Zaretskii, Stephen Leake, Emacs development discussions >>> * fixnum <-> int64_t is the only type conversion supported >> Not sure I understand: can the C side see "Lisp_Object" (presumably as >> an opaque type)? > As I'm imagining the system, no. Access is indirected. That insulates C > code from Emacs GC requirements and lets us easily support global > references. But that forces a completely manual management of Lisp_Object references, making the interface a lot more painful to use. I must prefer exposing staticpro and conservative stack scanning. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-06 5:14 ` Stefan Monnier @ 2015-03-06 18:22 ` Daniel Colascione 2015-03-10 1:26 ` Stefan Monnier 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-03-06 18:22 UTC (permalink / raw) To: Stefan Monnier Cc: Aurélien Aptel, Eli Zaretskii, Stephen Leake, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 1182 bytes --] On 03/05/2015 09:14 PM, Stefan Monnier wrote: >>>> * fixnum <-> int64_t is the only type conversion supported >>> Not sure I understand: can the C side see "Lisp_Object" (presumably as >>> an opaque type)? >> As I'm imagining the system, no. Access is indirected. That insulates C >> code from Emacs GC requirements and lets us easily support global >> references. > > But that forces a completely manual management of Lisp_Object > references, making the interface a lot more painful to use. > I must prefer exposing staticpro and conservative stack scanning. Reasonable people can differ on the conservative scanning issue (JSC does it; V8 and Java don't). If we bake the assumption of conservative scanning into the interface, we're going to regret it later. In practice, manually managing references is no trouble at all since most Lisp->C code is call-response, and we automatically unwind references when C functions return. I have to insist on not requiring staticpro, at least in its present form. Registration of new GC roots (i.e., global references) must be dynamic. You can't possibly predict the reference models modules might want to use. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-06 18:22 ` Daniel Colascione @ 2015-03-10 1:26 ` Stefan Monnier 0 siblings, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2015-03-10 1:26 UTC (permalink / raw) To: Daniel Colascione Cc: Aurélien Aptel, Eli Zaretskii, Stephen Leake, Emacs development discussions > Reasonable people can differ on the conservative scanning issue (JSC > does it; V8 and Java don't). If we bake the assumption of conservative > scanning into the interface, we're going to regret it later. Yes, if we define the API as using conservative stack scanning, then when we change to a GC that doesn't use conservative stack scanning, all the plugins will need to be changed correspondingly. Of course, when/if we make that change, we'll also have to make the same changes to Emacs's own code. My take on it is that making the changes to Emacs itself will be a crapload more painful than fixing the few affected plugins, so I'm really not worried about this eventuality. > I have to insist on not requiring staticpro, at least in its present > form. Registration of new GC roots (i.e., global references) must be > dynamic. Of course it should be. I didn't mean to take the current implementation of staticpro and expose it as is. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-28 18:20 ` Aurélien Aptel 2015-03-04 13:48 ` Stephen Leake 2015-03-04 22:34 ` Stefan Monnier @ 2015-03-05 17:19 ` Stephen Leake 2015-03-05 22:32 ` Stephen Leake 2015-03-16 18:02 ` Stephen Leake 4 siblings, 0 replies; 765+ messages in thread From: Stephen Leake @ 2015-03-05 17:19 UTC (permalink / raw) To: emacs-devel Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: > I've tried to implement modules using Daniel's plan. > The code is available on my github repo on the dynamic-modules-2 branch. > The interesting parts are the API header, the runtime and the sample module. > > git repo: https://github.com/aaptel/emacs-dynamic-module.git Why do we need both emacs_runtime and emacs_env types? If the function pointers in emacs_env were in emacs_runtime instead, what would we lose? It seems every module will need 'bind_function', so perhaps that should be in emacs_module.h. I'll work on implementing the ada-mode parser with this, to illuminate other issues. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-28 18:20 ` Aurélien Aptel ` (2 preceding siblings ...) 2015-03-05 17:19 ` Stephen Leake @ 2015-03-05 22:32 ` Stephen Leake 2015-03-13 16:47 ` Stephen Leake 2015-03-16 18:02 ` Stephen Leake 4 siblings, 1 reply; 765+ messages in thread From: Stephen Leake @ 2015-03-05 22:32 UTC (permalink / raw) To: emacs-devel Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: > $ ./src/emacs -Q > (module-load "./modules/basic/basic.so") > => t > > (basic-sum 2 2) > => 4 > > git repo: https://github.com/aaptel/emacs-dynamic-module.git This compiles and runs for me on 64 bit Debian and 32 bit Mingw. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-05 22:32 ` Stephen Leake @ 2015-03-13 16:47 ` Stephen Leake 2015-03-13 18:37 ` Ivan Shmakov 0 siblings, 1 reply; 765+ messages in thread From: Stephen Leake @ 2015-03-13 16:47 UTC (permalink / raw) To: emacs-devel Stephen Leake <stephen_leake@stephe-leake.org> writes: > Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: > >> $ ./src/emacs -Q >> (module-load "./modules/basic/basic.so") >> => t >> >> (basic-sum 2 2) >> => 4 >> >> git repo: https://github.com/aaptel/emacs-dynamic-module.git > > This compiles and runs for me on 64 bit Debian and 32 bit Mingw. However, when I try to access an elisp vector, it fails: ---- test_module_vector.c #include <emacs_module.h> int plugin_is_GPL_compatible; /* functions */ static emacs_value length; /* standard Emacs module init */ int emacs_module_init (struct emacs_runtime *ert) { emacs_env *env = ert->get_environment (ert); length = env->intern (env, "length"); emacs_value names = env->intern (env, "ada_grammar-names"); emacs_value args[] = { names }; int64_t names_length = env->fixnum_to_int (env, env->funcall (env, length, 1, args)); return 0; } ---- test_module_vector.c (setq ada_grammar-names [0 1 2 3 4]) (sequencep ada_grammar-names) (length ada_grammar-names) (module-load "test_module_vector.dll") => module-load: Wrong type argument: sequencep, ada_grammar-names This happens on both Windows Mingw32 and Debian x86_64 -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-13 16:47 ` Stephen Leake @ 2015-03-13 18:37 ` Ivan Shmakov 2015-03-15 10:46 ` Stephen Leake 0 siblings, 1 reply; 765+ messages in thread From: Ivan Shmakov @ 2015-03-13 18:37 UTC (permalink / raw) To: emacs-devel >>>>> Stephen Leake <stephen_leake@stephe-leake.org> writes: […] > However, when I try to access an elisp vector, it fails: […] > emacs_value names = env->intern (env, "ada_grammar-names"); > emacs_value args[] = { names }; > int64_t names_length = env->fixnum_to_int (env, env->funcall (env, length, 1, args)); Isn’t the above essentially (length 'ada_grammar-names)? Or, verbosely speaking: (let* ((length (intern "length")) (names (intern "ada_grammar-names")) (names-length (funcall length names))) …) (That is, the code above wants to apply 'length to the /value/ of a variable – not its /name/.) […] > => module-load: Wrong type argument: sequencep, ada_grammar-names > This happens on both Windows Mingw32 and Debian x86_64 -- FSF associate member #7257 http://boycottsystemd.org/ … 3013 B6A0 230E 334A ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-13 18:37 ` Ivan Shmakov @ 2015-03-15 10:46 ` Stephen Leake 0 siblings, 0 replies; 765+ messages in thread From: Stephen Leake @ 2015-03-15 10:46 UTC (permalink / raw) To: emacs-devel Ivan Shmakov <ivan@siamics.net> writes: >>>>>> Stephen Leake <stephen_leake@stephe-leake.org> writes: > > […] > > > However, when I try to access an elisp vector, it fails: > > […] > > > emacs_value names = env->intern (env, "ada_grammar-names"); > > emacs_value args[] = { names }; > > int64_t names_length = env->fixnum_to_int (env, env->funcall (env, length, 1, args)); > > Isn’t the above essentially (length 'ada_grammar-names)? Or, > verbosely speaking: > > (let* ((length (intern "length")) > (names (intern "ada_grammar-names")) > (names-length (funcall length names))) > …) > > (That is, the code above wants to apply 'length to the /value/ > of a variable – not its /name/.) Yes, that's it. Fixed by adding a call to 'symbol-value'. It might be good to add a C-level env->symbol_value for this purpose. Thanks, -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-28 18:20 ` Aurélien Aptel ` (3 preceding siblings ...) 2015-03-05 22:32 ` Stephen Leake @ 2015-03-16 18:02 ` Stephen Leake 2015-03-17 9:28 ` Aurélien Aptel ` (2 more replies) 4 siblings, 3 replies; 765+ messages in thread From: Stephen Leake @ 2015-03-16 18:02 UTC (permalink / raw) To: emacs-devel Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: > I've tried to implement modules using Daniel's plan. It turned out to > be pretty easy, mostly because I'm more familiar with the Emacs > codebase now and because it's a lot less intrusive than my previous > attempt. > > It's not finished but I have a basic module working on linux. It's a > proof of concept, basically. I've implemented a test module that calls two Ada mode parser actions (see below). The real module will call the actual parser and build the action args from the parse results. I did not have to modify anything in the Emacs C code to make this work, so it shows this module design is adquate for my use case so far. I still need to implement the lexer level, which will either need to call the current elisp lexer, or access the buffer text directly. Any comments on the coding style? I don't think I need GCPRO on any of the static emacs_values, because they are all declared at global level in elisp. -- -- Stephe /* Emacs module for Ada mode, providing a fast generalized LALR parser */ #include <emacs_module.h> int plugin_is_GPL_compatible; /* elisp functions */ static emacs_value aref; static emacs_value cons; static emacs_value length; static emacs_value nil; static emacs_value set; static emacs_value symbol_value; static emacs_value vector; static emacs_value wisi_containing_action; static emacs_value wisi_statement_action; /* variables */ static emacs_value wisi_tokens; /* array of symbols used in grammar actions */ static emacs_value* ada_grammar_names; static emacs_value Fcons (emacs_env *env, emacs_value a, emacs_value b) { emacs_value args[] = { a, b }; return env->funcall (env, cons, 2, args); } /* Parse BUFFER, using parser in current module. */ static void parse (emacs_env *env, emacs_value buffer) { /* For now, just execute the actions from parsing second line in: procedure Foo is begin A := 1; end Foo; ada_grammar.adb assignment_statement_0 wisi-tokens: [(name 24 . 25) (COLON_EQUAL 26 . 28) (expression 29 . 30) (SEMICOLON 30 . 31)] action: (wisi-statement-action [1 statement-start 2 statement-other 4 statement-end]) */ /* Set `wisi-tokens'; wisi-tokens is let-bound in calling elisp function. */ emacs_value tokens[] = { /* name "A" */ Fcons (env, ada_grammar_names[245], Fcons (env, env->make_fixnum (env, 24), env->make_fixnum (env, 25))), /* COLON_EQUAL ":=" */ Fcons (env, ada_grammar_names[ 81], Fcons (env, env->make_fixnum (env, 26), env->make_fixnum (env, 28))), /* expression "1" */ Fcons (env, ada_grammar_names[194], Fcons (env, env->make_fixnum (env, 29), env->make_fixnum (env, 30))), /* SEMICOLON ";" */ Fcons (env, ada_grammar_names[ 95], Fcons (env, env->make_fixnum (env, 30), env->make_fixnum (env, 31))) }; emacs_value args_1[] = { wisi_tokens, env->funcall (env, vector, 4, tokens) }; env->funcall (env, set, 2, args_1); emacs_value pairs[] = { env->make_fixnum (env, 1), ada_grammar_names[341], /* statement-start */ env->make_fixnum (env, 2), ada_grammar_names[342], /* statement-other */ env->make_fixnum (env, 4), ada_grammar_names[343] /* statement-end */ }; emacs_value args_2[] = { env->funcall (env, vector, 6, pairs) }; env->funcall (env, wisi_statement_action, 1, args_2); emacs_value args_3[] = { env->make_fixnum (env, 2), env->make_fixnum (env, 3) }; env->funcall (env, wisi_containing_action, 2, args_3); } /* elisp-callable wrapper for `parse' args: BUFFER */ static emacs_value Fparse (emacs_env *env, int nargs, emacs_value args[]) { parse (env, args[0]); return nil; } /* Binds NAME to FUN */ static void bind_function (emacs_env *env, const char *name, emacs_value Ffun) { emacs_value Qfset = env->intern (env, "fset"); emacs_value Qsym = env->intern (env, name); emacs_value args[] = { Qsym, Ffun }; env->funcall (env, Qfset, 2, args); } /* standard Emacs module init */ int emacs_module_init (struct emacs_runtime *ert) { emacs_env *env = ert->get_environment (ert); aref = env->intern (env, "aref"); cons = env->intern (env, "cons"); length = env->intern (env, "length"); nil = env->intern (env, "nil"); set = env->intern (env, "set"); symbol_value = env->intern (env, "symbol-value"); vector = env->intern (env, "vector"); wisi_statement_action = env->intern (env, "wisi-statement-action"); wisi_containing_action = env->intern (env, "wisi-containing-action"); wisi_tokens = env->intern (env, "wisi-tokens"); emacs_value names_1 = env->intern (env, "ada_grammar-names"); emacs_value args_1[] = { names_1 }; emacs_value names_2 = env->funcall (env, symbol_value, 1, args_1); emacs_value args_2[] = { names_2 }; int64_t names_length = env->fixnum_to_int (env, env->funcall (env, length, 1, args_2)); ada_grammar_names = malloc (names_length * sizeof (int64_t)); for (int i = 0; i < names_length; i++) { emacs_value args[] = {names_2, env->make_fixnum (env, i)}; ada_grammar_names[i] = env->funcall (env, aref, 2, args); }; bind_function (env, "wisi-module-parse", env->make_function (env, 1, 1, Fparse)); return 0; } ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-16 18:02 ` Stephen Leake @ 2015-03-17 9:28 ` Aurélien Aptel 2015-03-17 9:52 ` Eli Zaretskii 2015-03-17 14:50 ` Stephen Leake 2015-03-24 21:08 ` Stephen Leake 2015-05-06 4:11 ` Dynamic loading progress; funcall of goto-char fails Stephen Leake 2 siblings, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-03-17 9:28 UTC (permalink / raw) To: Stephen Leake; +Cc: Emacs development discussions On Mon, Mar 16, 2015 at 7:02 PM, Stephen Leake <stephen_leake@stephe-leake.org> wrote: > I've implemented a test module that calls two Ada mode parser actions > (see below). > > The real module will call the actual parser and build the action args > from the parse results. > > I did not have to modify anything in the Emacs C code to make this work, > so it shows this module design is adquate for my use case so far. Good! I'd be interested in performance comparison between the pure elisp version and this module version. I suspect it's not going to be much unfortunately. You module doesn't seem to be resource intensive (as of now) anyway. > I still need to implement the lexer level, which will either need to > call the current elisp lexer, or access the buffer text directly. No buffer or string access yet, sorry. I guess you can work around it by retrieving each character as an int but that's neither practical nor efficient. > Any comments on the coding style? I don't think I need GCPRO on any of There's no GC protection in the module API yet. I think there are some place of your module that might not be safe. See below. > the static emacs_values, because they are all declared at global level > in elisp. I had not thought about that: global refs can be defined in pure elisp. That indeed removes the need for registering global values via the module API. I'm still not sure I understand what Daniel had in mind for global/local value registration, I'm kind of waiting for his reply to move forward. I'll try reading more thoroughly the JNI document he linked in a previous message in the meantime. > emacs_value tokens[] = > { /* name "A" */ > Fcons (env, ada_grammar_names[245], Fcons (env, env->make_fixnum (env, 24), env->make_fixnum (env, 25))), > > /* COLON_EQUAL ":=" */ > Fcons (env, ada_grammar_names[ 81], Fcons (env, env->make_fixnum (env, 26), env->make_fixnum (env, 28))), > > /* expression "1" */ > Fcons (env, ada_grammar_names[194], Fcons (env, env->make_fixnum (env, 29), env->make_fixnum (env, 30))), > > /* SEMICOLON ";" */ > Fcons (env, ada_grammar_names[ 95], Fcons (env, env->make_fixnum (env, 30), env->make_fixnum (env, 31))) > }; ^^^^ all those conses can be GC'd if any of the code afterwards can call the GC. It might not be the case right now put it probably will at some point. I'm not sure about this but if you call a pure-elisp function the GC will trigger. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-17 9:28 ` Aurélien Aptel @ 2015-03-17 9:52 ` Eli Zaretskii 2015-03-17 10:51 ` Aurélien Aptel 2015-03-17 16:37 ` Stefan Monnier 2015-03-17 14:50 ` Stephen Leake 1 sibling, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-03-17 9:52 UTC (permalink / raw) To: Aurélien Aptel; +Cc: stephen_leake, emacs-devel > Date: Tue, 17 Mar 2015 10:28:13 +0100 > From: Aurélien Aptel <aurelien.aptel+emacs@gmail.com> > Cc: Emacs development discussions <emacs-devel@gnu.org> > > > I still need to implement the lexer level, which will either need to > > call the current elisp lexer, or access the buffer text directly. > > No buffer or string access yet, sorry. I guess you can work around it > by retrieving each character as an int but that's neither practical > nor efficient. Actually, most accesses to buffer text do precisely that: access one character at a time. The API typically accepts the buffer position. Why do you think this is inefficient? If we think modules will need to access lexical units, we might provide APIs for that, although I expect this to be complicated, due to the different semantics of what a "word" etc. is, buffer-local syntax tables, and other complications. Direct access to buffer text as a C array is also a possibility, but modules that do that will have to handle the gap, and also cope with buffer relocation (on platforms that use ralloc.c). ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-17 9:52 ` Eli Zaretskii @ 2015-03-17 10:51 ` Aurélien Aptel 2015-03-17 11:08 ` Eli Zaretskii 2015-03-17 16:37 ` Stefan Monnier 1 sibling, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-03-17 10:51 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Stephen Leake, Emacs development discussions On Tue, Mar 17, 2015 at 10:52 AM, Eli Zaretskii <eliz@gnu.org> wrote: > Actually, most accesses to buffer text do precisely that: access one > character at a time. The API typically accepts the buffer position. > Why do you think this is inefficient? Iterating on a buffer content will need, for each character (I think) 2 funcalls (char-after, forward-char) and a fixnum -> int64_t conversion. It seems like a non-negligible overhead, but maybe it isn't, I don't know... ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-17 10:51 ` Aurélien Aptel @ 2015-03-17 11:08 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-03-17 11:08 UTC (permalink / raw) To: Aurélien Aptel; +Cc: stephen_leake, emacs-devel > Date: Tue, 17 Mar 2015 11:51:44 +0100 > From: Aurélien Aptel <aurelien.aptel+emacs@gmail.com> > Cc: Stephen Leake <stephen_leake@stephe-leake.org>, > Emacs development discussions <emacs-devel@gnu.org> > > On Tue, Mar 17, 2015 at 10:52 AM, Eli Zaretskii <eliz@gnu.org> wrote: > > Actually, most accesses to buffer text do precisely that: access one > > character at a time. The API typically accepts the buffer position. > > Why do you think this is inefficient? > > Iterating on a buffer content will need, for each character (I think) > 2 funcalls (char-after, forward-char) and a fixnum -> int64_t > conversion. It seems like a non-negligible overhead, but maybe it > isn't, I don't know... Why do we need to go through char-after, with the induced fixnum conversion? Why not simply return a character, which we know in advance will fit into a C 'int'? Once again, what I had in mind is a function that gets buffer position and returns the character at that position, as a C 'int'. That's all. I see no reason to go through Lisp primitives for that job. Maybe I'm missing something. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-17 9:52 ` Eli Zaretskii 2015-03-17 10:51 ` Aurélien Aptel @ 2015-03-17 16:37 ` Stefan Monnier 2015-03-17 17:08 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Stefan Monnier @ 2015-03-17 16:37 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Aurélien Aptel, stephen_leake, emacs-devel > Actually, most accesses to buffer text do precisely that: access one > character at a time. The API typically accepts the buffer position. > Why do you think this is inefficient? For efficient parsing (as done by forward-word, forward-sexp and friends), I think you need to keep both the current "charpos" and "bytepos", but Elisp interfaces don't give access to this level. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-17 16:37 ` Stefan Monnier @ 2015-03-17 17:08 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-03-17 17:08 UTC (permalink / raw) To: Stefan Monnier; +Cc: aurelien.aptel+emacs, stephen_leake, emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Cc: Aurélien Aptel <aurelien.aptel+emacs@gmail.com>, > stephen_leake@stephe-leake.org, emacs-devel@gnu.org > Date: Tue, 17 Mar 2015 12:37:27 -0400 > > > Actually, most accesses to buffer text do precisely that: access one > > character at a time. The API typically accepts the buffer position. > > Why do you think this is inefficient? > > For efficient parsing (as done by forward-word, forward-sexp and > friends), I think you need to keep both the current "charpos" and > "bytepos", but Elisp interfaces don't give access to this level. The API we provide for accessing buffer text should handle that as well. For example, we could model it on FETCH_CHAR_ADVANCE. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-17 9:28 ` Aurélien Aptel 2015-03-17 9:52 ` Eli Zaretskii @ 2015-03-17 14:50 ` Stephen Leake 1 sibling, 0 replies; 765+ messages in thread From: Stephen Leake @ 2015-03-17 14:50 UTC (permalink / raw) To: emacs-devel Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: > On Mon, Mar 16, 2015 at 7:02 PM, Stephen Leake > <stephen_leake@stephe-leake.org> wrote: >> I've implemented a test module that calls two Ada mode parser actions >> (see below). >> >> The real module will call the actual parser and build the action args >> from the parse results. >> >> I did not have to modify anything in the Emacs C code to make this work, >> so it shows this module design is adquate for my use case so far. > > Good! I'd be interested in performance comparison between the pure > elisp version and this module version. I suspect it's not going to be > much unfortunately. You module doesn't seem to be resource intensive > (as of now) anyway. It doesn't currently do anything; it just explors how to call elisp from the module. It will eventually call the full lexer and parser. >> I still need to implement the lexer level, which will either need to >> call the current elisp lexer, or access the buffer text directly. > > No buffer or string access yet, sorry. I guess you can work around it > by retrieving each character as an int but that's neither practical > nor efficient. Right. But I'd like to try calling the ada-mode elisp lexer function anyway; less code to port to the module, and I suspect it's faster. >> emacs_value tokens[] = >> { /* name "A" */ >> Fcons (env, ada_grammar_names[245], Fcons (env, env->make_fixnum (env, 24), env->make_fixnum (env, 25))), >> >> /* COLON_EQUAL ":=" */ >> Fcons (env, ada_grammar_names[ 81], Fcons (env, env->make_fixnum (env, 26), env->make_fixnum (env, 28))), >> >> /* expression "1" */ >> Fcons (env, ada_grammar_names[194], Fcons (env, env->make_fixnum (env, 29), env->make_fixnum (env, 30))), >> >> /* SEMICOLON ";" */ >> Fcons (env, ada_grammar_names[ 95], Fcons (env, env->make_fixnum (env, 30), env->make_fixnum (env, 31))) >> }; > > ^^^^ all those conses can be GC'd if any of the code afterwards can > call the GC. It might not be the case right now put it probably will > at some point. I'm not sure about this but if you call a pure-elisp > function the GC will trigger. Right. This is a temporary list built as an argument to an elisp call. I want it to be garbage collected after the call, but not during. module_funcall in module.c copies the args (shallow copy only) and does GCPRO1 on the copy (actually on the first element of the copy), then does the actual funcall, followed by GCUNPRO. Is that sufficient? On the other hand, can we eliminate the copy to save time? I think all we need to do is include 'fun' in 'args', as the standard lisp syntax does. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-03-16 18:02 ` Stephen Leake 2015-03-17 9:28 ` Aurélien Aptel @ 2015-03-24 21:08 ` Stephen Leake 2015-05-06 4:11 ` Dynamic loading progress; funcall of goto-char fails Stephen Leake 2 siblings, 0 replies; 765+ messages in thread From: Stephen Leake @ 2015-03-24 21:08 UTC (permalink / raw) To: emacs-devel Stephen Leake <stephen_leake@stephe-leake.org> writes: > Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: > >> I've tried to implement modules using Daniel's plan. It turned out to >> be pretty easy, mostly because I'm more familiar with the Emacs >> codebase now and because it's a lot less intrusive than my previous >> attempt. >> >> It's not finished but I have a basic module working on linux. It's a >> proof of concept, basically. > > I've implemented a test module that calls two Ada mode parser actions > (see below). I've now translated that test module into Ada, and that version also works on both Windows and Debian. It is far easier to import this emacs_module.h into Ada than the subset of lisp.h in the other dynamic modules approach. It will also be easier for other module implementation languages to use. So I suggest we adopt this approach as the way forward. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress; funcall of goto-char fails 2015-03-16 18:02 ` Stephen Leake 2015-03-17 9:28 ` Aurélien Aptel 2015-03-24 21:08 ` Stephen Leake @ 2015-05-06 4:11 ` Stephen Leake 2015-05-06 4:21 ` Daniel Colascione 2 siblings, 1 reply; 765+ messages in thread From: Stephen Leake @ 2015-05-06 4:11 UTC (permalink / raw) To: emacs-devel Stephen Leake <stephen_leake@stephe-leake.org> writes: > Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: > >> I've tried to implement modules using Daniel's plan. It turned out to >> be pretty easy, mostly because I'm more familiar with the Emacs >> codebase now and because it's a lot less intrusive than my previous >> attempt. >> >> It's not finished but I have a basic module working on linux. It's a >> proof of concept, basically. > > I've implemented a test module that calls two Ada mode parser actions > (see below). > > The real module will call the actual parser and build the action args > from the parse results. > > I did not have to modify anything in the Emacs C code to make this work, > so it shows this module design is adquate for my use case so far. I've made more progress; I've got a module that should run the full Ada parser on a buffer. However, when I run it, it crashes on a call like: emacs_value goto_char_sym = env.intern (env, "goto-char"); env.funcall (env, goto_char_sym, env.make_fixnum (env, 1)); When I trace the 'funcall' (in eval.c DEFUN funcall), it hits this code: fun = original_fun; if (SYMBOLP (fun) && !NILP (fun) && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) fun = indirect_function (fun); and sets fun to 0, which then signals a failure. Is this because 'goto-char' is implemented in C? If so, I need a way to call elisp functions implemented in C. Hmm. I guess for now I can provide elisp wrappers for all the functions I need. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress; funcall of goto-char fails 2015-05-06 4:11 ` Dynamic loading progress; funcall of goto-char fails Stephen Leake @ 2015-05-06 4:21 ` Daniel Colascione 2015-05-06 8:15 ` Stephen Leake 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-05-06 4:21 UTC (permalink / raw) To: Stephen Leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1687 bytes --] On 05/05/2015 09:11 PM, Stephen Leake wrote: > Stephen Leake <stephen_leake@stephe-leake.org> writes: > >> Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: >> >>> I've tried to implement modules using Daniel's plan. It turned out to >>> be pretty easy, mostly because I'm more familiar with the Emacs >>> codebase now and because it's a lot less intrusive than my previous >>> attempt. >>> >>> It's not finished but I have a basic module working on linux. It's a >>> proof of concept, basically. >> >> I've implemented a test module that calls two Ada mode parser actions >> (see below). >> >> The real module will call the actual parser and build the action args >> from the parse results. >> >> I did not have to modify anything in the Emacs C code to make this work, >> so it shows this module design is adquate for my use case so far. > > I've made more progress; I've got a module that should run the full Ada > parser on a buffer. > > However, when I run it, it crashes on a call like: > > emacs_value goto_char_sym = env.intern (env, "goto-char"); > env.funcall (env, goto_char_sym, env.make_fixnum (env, 1)); > > When I trace the 'funcall' (in eval.c DEFUN funcall), it hits this code: > > fun = original_fun; > if (SYMBOLP (fun) && !NILP (fun) > && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) > fun = indirect_function (fun); > > and sets fun to 0, which then signals a failure. > > Is this because 'goto-char' is implemented in C? That's odd. Why would it matter? For me, (symbol-function 'goto-char) is a subr, so the second SYMBOLP above should fail and `fun' should be a subr object, not nil. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress; funcall of goto-char fails 2015-05-06 4:21 ` Daniel Colascione @ 2015-05-06 8:15 ` Stephen Leake 0 siblings, 0 replies; 765+ messages in thread From: Stephen Leake @ 2015-05-06 8:15 UTC (permalink / raw) To: emacs-devel Daniel Colascione <dancol@dancol.org> writes: > On 05/05/2015 09:11 PM, Stephen Leake wrote: >> Stephen Leake <stephen_leake@stephe-leake.org> writes: >> >>> Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: >>> >>>> I've tried to implement modules using Daniel's plan. It turned out to >>>> be pretty easy, mostly because I'm more familiar with the Emacs >>>> codebase now and because it's a lot less intrusive than my previous >>>> attempt. >>>> >>>> It's not finished but I have a basic module working on linux. It's a >>>> proof of concept, basically. >>> >>> I've implemented a test module that calls two Ada mode parser actions >>> (see below). >>> >>> The real module will call the actual parser and build the action args >>> from the parse results. >>> >>> I did not have to modify anything in the Emacs C code to make this work, >>> so it shows this module design is adquate for my use case so far. >> >> I've made more progress; I've got a module that should run the full Ada >> parser on a buffer. >> >> However, when I run it, it crashes on a call like: >> >> emacs_value goto_char_sym = env.intern (env, "goto-char"); >> env.funcall (env, goto_char_sym, env.make_fixnum (env, 1)); >> >> When I trace the 'funcall' (in eval.c DEFUN funcall), it hits this code: >> >> fun = original_fun; >> if (SYMBOLP (fun) && !NILP (fun) >> && (fun = XSYMBOL (fun)->function, SYMBOLP (fun))) >> fun = indirect_function (fun); >> >> and sets fun to 0, which then signals a failure. >> >> Is this because 'goto-char' is implemented in C? > > That's odd. Why would it matter? For me, (symbol-function 'goto-char) is > a subr, so the second SYMBOLP above should fail and `fun' should be a > subr object, not nil. Never mind; I found the problem. Due to a cut-and-paste error, I spelled "goto-char" as "goto_char". And since intern-soft is not currently in emacs_module.h, I used intern, which of course returned a non-function symbol instead of an error. All better now. Sorry for the noise. I will have a list of suggestions to add to emacs_module.h once I get this working. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-17 17:46 ` Aurélien Aptel 2015-02-17 17:50 ` Aurélien Aptel 2015-02-17 18:04 ` Daniel Colascione @ 2015-02-17 18:06 ` Eli Zaretskii 2015-02-17 18:20 ` Steinar Bang 2015-02-18 0:55 ` Stephen J. Turnbull 3 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-02-17 18:06 UTC (permalink / raw) To: Aurélien Aptel; +Cc: dancol, stephen_leake, emacs-devel > Date: Tue, 17 Feb 2015 18:46:33 +0100 > From: Aurélien Aptel <aurelien.aptel+emacs@gmail.com> > Cc: Daniel Colascione <dancol@dancol.org>, Stephen Leake <stephen_leake@stephe-leake.org>, > Emacs development discussions <emacs-devel@gnu.org> > > We should call `provide' in the module (like in my module branch) > using the API. Problem solved? It will be solved if there's a provide function available in the interface. Daniel's suggestion didn't include it, which is why I asked about that. Daniel seems to be unconvinced that it's needed. > Concerning docstrings, we just have to teach the makedoc utility how > to extract them from this new module system. Extract them to which place? Besides, make-docfile is not installed with Emacs, and so will probably be unavailable when the module is built. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-17 18:06 ` Dynamic loading progress Eli Zaretskii @ 2015-02-17 18:20 ` Steinar Bang 0 siblings, 0 replies; 765+ messages in thread From: Steinar Bang @ 2015-02-17 18:20 UTC (permalink / raw) To: emacs-devel >>>>> Eli Zaretskii <eliz@gnu.org>: >> From: Aurélien Aptel <aurelien.aptel+emacs@gmail.com> >> We should call `provide' in the module (like in my module branch) >> using the API. Problem solved? > It will be solved if there's a provide function available in the > interface. Daniel's suggestion didn't include it, which is why I > asked about that. Daniel seems to be unconvinced that it's needed. Perhaps like so...? emacs_eval(env, "(provide 'mymodule)"); ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-17 17:46 ` Aurélien Aptel ` (2 preceding siblings ...) 2015-02-17 18:06 ` Dynamic loading progress Eli Zaretskii @ 2015-02-18 0:55 ` Stephen J. Turnbull 3 siblings, 0 replies; 765+ messages in thread From: Stephen J. Turnbull @ 2015-02-18 0:55 UTC (permalink / raw) To: Aurélien Aptel Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions Aurélien Aptel writes: > I'm with Eli on the versionning choice Versioning is a poor choice here for the same reasons it almost always is. Dan's design means that the module doesn't need to care about the implementation, except for the usual reasons of breaking promises about semantics. It's equivalent to the recommended design of using feature tests rather than version tests. > but it's just bike shedding at this point. With Dan's design, there's nothing left *but* bikeshedding, Brother Aurélien. It solves problems I didn't know XEmacs's design has. > Interning all the time seems tedious and probably (a bit?) slow but > moving the interning on Emacs side won't change the slow part. It's not detectably slow, especially if you cache the result, and the intern-and-cache process can be performed by a macro in module_api.h or by a function exported from Emacs. A little bit of elisp for collecting and decorating the names you need in a module init function, and it's bearable tedium. This is based on a decade and a half of experience with XEmacs's "ELL" module system. > At least on the module side you can do it once and reuse the > result. Or maybe you shouldn't if the user changes the binding in > the meantime? I'm not sure about Dan's "one more indirection" design, but in the case where you use the result of intern directly, this has the expected semantics: the user's change wins. Dan's design should have the same semantics, I'm guessing. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 20:20 ` Daniel Colascione 2015-02-16 14:05 ` Aurélien Aptel 2015-02-16 15:43 ` Eli Zaretskii @ 2015-09-13 13:04 ` Philipp Stephani 2015-09-13 14:15 ` Daniel Colascione 2015-10-04 8:57 ` Philipp Stephani 3 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-09-13 13:04 UTC (permalink / raw) To: Daniel Colascione, Eli Zaretskii; +Cc: stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 436 bytes --] Daniel Colascione <dancol@dancol.org> schrieb am So., 15. Feb. 2015 um 21:21 Uhr: > typedef struct emacs_value_tag* emacs_value; > Would it make sense to not use a typedef here? Using a typedef means that the type including its size is opaque and subject to change, which can break ABI compatibility. I'd rather have something like: struct emacs_value { // contains private fields }; and then pass *struct emacs_value** around. [-- Attachment #2: Type: text/html, Size: 780 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-13 13:04 ` Philipp Stephani @ 2015-09-13 14:15 ` Daniel Colascione 2015-09-13 14:27 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-09-13 14:15 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii; +Cc: stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 818 bytes --] On 09/13/2015 06:04 AM, Philipp Stephani wrote: > Daniel Colascione <dancol@dancol.org <mailto:dancol@dancol.org>> schrieb > am So., 15. Feb. 2015 um 21:21 Uhr: > > typedef struct emacs_value_tag* emacs_value; > > > Would it make sense to not use a typedef here? Using a typedef means > that the type including its size is opaque and subject to change, which > can break ABI compatibility. I'd rather have something like: > > struct emacs_value { > // contains private fields > }; > > and then pass /struct emacs_value*/ around. You may have missed the "*" in the typedef. The difference is stylistic. There's no difference between foo and bar here. typedef struct valuex* value; void foo(struct valuex* x); void bar(value y); I find the typedef much more readable, however. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-13 14:15 ` Daniel Colascione @ 2015-09-13 14:27 ` Philipp Stephani 2015-09-13 14:31 ` Daniel Colascione 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-09-13 14:27 UTC (permalink / raw) To: Daniel Colascione, Eli Zaretskii; +Cc: stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1169 bytes --] Daniel Colascione <dancol@dancol.org> schrieb am So., 13. Sep. 2015 um 16:15 Uhr: > On 09/13/2015 06:04 AM, Philipp Stephani wrote: > > Daniel Colascione <dancol@dancol.org <mailto:dancol@dancol.org>> schrieb > > am So., 15. Feb. 2015 um 21:21 Uhr: > > > > typedef struct emacs_value_tag* emacs_value; > > > > > > Would it make sense to not use a typedef here? Using a typedef means > > that the type including its size is opaque and subject to change, which > > can break ABI compatibility. I'd rather have something like: > > > > struct emacs_value { > > // contains private fields > > }; > > > > and then pass /struct emacs_value*/ around. > > You may have missed the "*" in the typedef. The difference is stylistic. > There's no difference between foo and bar here. > > typedef struct valuex* value; > void foo(struct valuex* x); > void bar(value y); > > I find the typedef much more readable, however. > > There's no difference in your design, but using a typedef makes it possible to use a non-pointer type without changing the API in obvious ways. E.g. Linus is strongly against such typedefs: http://lkml.iu.edu/hypermail/linux/kernel/0206.1/0402.html [-- Attachment #2: Type: text/html, Size: 1799 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-13 14:27 ` Philipp Stephani @ 2015-09-13 14:31 ` Daniel Colascione 2015-09-28 15:05 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-09-13 14:31 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii; +Cc: stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1713 bytes --] On 09/13/2015 07:27 AM, Philipp Stephani wrote: > Daniel Colascione <dancol@dancol.org <mailto:dancol@dancol.org>> schrieb > am So., 13. Sep. 2015 um 16:15 Uhr: > > On 09/13/2015 06:04 AM, Philipp Stephani wrote: > > Daniel Colascione <dancol@dancol.org <mailto:dancol@dancol.org> > <mailto:dancol@dancol.org <mailto:dancol@dancol.org>>> schrieb > > am So., 15. Feb. 2015 um 21:21 Uhr: > > > > typedef struct emacs_value_tag* emacs_value; > > > > > > Would it make sense to not use a typedef here? Using a typedef means > > that the type including its size is opaque and subject to change, > which > > can break ABI compatibility. I'd rather have something like: > > > > struct emacs_value { > > // contains private fields > > }; > > > > and then pass /struct emacs_value*/ around. > > You may have missed the "*" in the typedef. The difference is stylistic. > There's no difference between foo and bar here. > > typedef struct valuex* value; > void foo(struct valuex* x); > void bar(value y); > > I find the typedef much more readable, however. > > > There's no difference in your design, but using a typedef makes it > possible to use a non-pointer type without changing the API in obvious > ways. > E.g. Linus is strongly against such > typedefs: http://lkml.iu.edu/hypermail/linux/kernel/0206.1/0402.html Linus is also against integer overflow checking. So what? I can't stand argumentum ad Linus. I still find the typedef more readable, because to users, emacs_value is an opaque type, and the fact that we implement it as a pointer is irrelevant. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-09-13 14:31 ` Daniel Colascione @ 2015-09-28 15:05 ` Philipp Stephani 0 siblings, 0 replies; 765+ messages in thread From: Philipp Stephani @ 2015-09-28 15:05 UTC (permalink / raw) To: Daniel Colascione, Eli Zaretskii; +Cc: stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 2130 bytes --] Daniel Colascione <dancol@dancol.org> schrieb am So., 13. Sep. 2015 um 16:31 Uhr: > On 09/13/2015 07:27 AM, Philipp Stephani wrote: > > Daniel Colascione <dancol@dancol.org <mailto:dancol@dancol.org>> schrieb > > am So., 13. Sep. 2015 um 16:15 Uhr: > > > > On 09/13/2015 06:04 AM, Philipp Stephani wrote: > > > Daniel Colascione <dancol@dancol.org <mailto:dancol@dancol.org> > > <mailto:dancol@dancol.org <mailto:dancol@dancol.org>>> schrieb > > > am So., 15. Feb. 2015 um 21:21 Uhr: > > > > > > typedef struct emacs_value_tag* emacs_value; > > > > > > > > > Would it make sense to not use a typedef here? Using a typedef > means > > > that the type including its size is opaque and subject to change, > > which > > > can break ABI compatibility. I'd rather have something like: > > > > > > struct emacs_value { > > > // contains private fields > > > }; > > > > > > and then pass /struct emacs_value*/ around. > > > > You may have missed the "*" in the typedef. The difference is > stylistic. > > There's no difference between foo and bar here. > > > > typedef struct valuex* value; > > void foo(struct valuex* x); > > void bar(value y); > > > > I find the typedef much more readable, however. > > > > > > There's no difference in your design, but using a typedef makes it > > possible to use a non-pointer type without changing the API in obvious > > ways. > > E.g. Linus is strongly against such > > typedefs: http://lkml.iu.edu/hypermail/linux/kernel/0206.1/0402.html > > Linus is also against integer overflow checking. So what? I can't stand > argumentum ad Linus. > > I still find the typedef more readable, because to users, emacs_value is > an opaque type, and the fact that we implement it as a pointer is > irrelevant. > > Fair enough, this is really just a minor nitpick. I was worried a bit to see it typedef'd to void* and cast to Lisp_Object in the implementation, which decreases type safety a bit and assumes that a Lisp object is always the size of a pointer, but probably that's minor and I worry too much. [-- Attachment #2: Type: text/html, Size: 3276 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 20:20 ` Daniel Colascione ` (2 preceding siblings ...) 2015-09-13 13:04 ` Philipp Stephani @ 2015-10-04 8:57 ` Philipp Stephani 2015-10-04 9:00 ` Eli Zaretskii 2015-10-04 9:10 ` Daniel Colascione 3 siblings, 2 replies; 765+ messages in thread From: Philipp Stephani @ 2015-10-04 8:57 UTC (permalink / raw) To: Daniel Colascione, Eli Zaretskii Cc: Aurélien Aptel, stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 3974 bytes --] Daniel Colascione <dancol@dancol.org> schrieb am So., 15. Feb. 2015 um 21:21 Uhr: > Here's a broad outline of what I have in mind. > Thanks, that looks really good. Just a few minor issues that I encountered over the last couple of weeks. > Thread-local environments > ------------------------- > > The `get_environment' member lets us do anything else interesting. As > in Java, environments are thread-local. We only support one thread for > the moment, so this constraint is easy to enforce. (Just abort if we > use an emacs_env off the main thread.) > Would you really abort, or rather use the error handling functions? We should be able to make the error values thread-local so that calling a function from the wrong thread would be the equivalent of raising a signal, giving the caller a chance to react. Otherwise the burden of remembering the correct thread would be on the caller's side. > typedef struct emacs_value_tag* emacs_value; > I think it's important that this is a pointer to a struct (for type safety and size correctness) rather than just an arbitrary type. > > typedef emacs_value (*emacs_subr)( > emacs_env* env, > int nargs, > emacs_value args[]); > Could we give this a void* data parameter for storing arbitrary user data? This is common for callbacks in C interfaces and allows C++ users to store C++ objects in the pointer. This can be implemented using another save pointer. > emacs_value (*make_function)( > emacs_env* env, > int min_arity, > int max_arity, > emacs_subr function); > Similary, here void* data should be passed to be retrieved later. > > emacs_value (*funcall)( > emacs_env* env, > emacs_value function, > int nargs, > emacs_value args[]); > Does function have to be a function object, or can it be a symbol? I.e. is the user supposed to call symbol-function first? > int64_t (*fixnum_to_int)( > emacs_env* env, > emacs_value value); > > emacs_value (*make_fixnum)( > emacs_env* env, > int64_t value); > > What's the behavior of these functions if the source would not fit into the result? Undefined behavior, abort(), raising a signal? > Modules can use make_global_reference to allocate a global reference > (i.e., a GC root) for any emacs_value; modules must then free these > references explicitly. > > All routines (except make_global_reference) that return emacs_value > values return local references. It's up to modules to register > long-lived references explicitly. > In which cases would global references be necessary? > Like JNI, we can just declare that it's illegal to call all but a few > specially-marked functions (like global reference deregistration) with > a pending error. > What's the behavior if other functions are called? abort()? > If Lisp signals or throws, `funcall' returns NULL. > Hmm, with the current implementation emacs_value is just the same as Lisp_Object, i.e. not a real pointer, so NULL doesn't have specific semantics. Should it return Qnil instead and force the user to use check_error? > 1) Do we need JNI-style local variable frames and functions that > release local references? > > 2) Maybe we want a separate, non-emacs_value type for global references? > No idea about these. > > 3) How exactly do we represent catch/throw values? > I've thought about this a bit, and I think it would be simplest to add a new function env->set_throw and have get_error and check_error return an enum { normal, signal, throw }. One could come up with something like creating a list (error-kind error-tag error-value), but it looks like the module implementation would create such lists only for the module code to convert them back, so it's simpler to represent the two kinds of non-local exits directly in the interface. > > 4) Do we need to use int64_t for integers? > Maybe just intmax_t and a static check that that is larger than an Elisp integer? [-- Attachment #2: Type: text/html, Size: 6266 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 8:57 ` Philipp Stephani @ 2015-10-04 9:00 ` Eli Zaretskii 2015-10-04 9:10 ` Daniel Colascione 1 sibling, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-10-04 9:00 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, dancol, stephen_leake, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sun, 04 Oct 2015 08:57:36 +0000 > Cc: stephen_leake@stephe-leake.org, emacs-devel@gnu.org, > Aurélien Aptel <aurelien.aptel+emacs@gmail.com> > > 4) Do we need to use int64_t for integers? > > Maybe just intmax_t and a static check that that is larger than an Elisp > integer? AFAIU, that will always fail in a 32-bit build --with-wide-int, right? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 8:57 ` Philipp Stephani 2015-10-04 9:00 ` Eli Zaretskii @ 2015-10-04 9:10 ` Daniel Colascione 2015-10-04 9:41 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-10-04 9:10 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii Cc: Aurélien Aptel, stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 5513 bytes --] On 10/04/2015 01:57 AM, Philipp Stephani wrote: > Daniel Colascione <dancol@dancol.org <mailto:dancol@dancol.org>> schrieb > am So., 15. Feb. 2015 um 21:21 Uhr: > > Here's a broad outline of what I have in mind. > > > Thanks, that looks really good. Just a few minor issues that I > encountered over the last couple of weeks. > > > Thread-local environments > ------------------------- > > The `get_environment' member lets us do anything else interesting. As > in Java, environments are thread-local. We only support one thread for > the moment, so this constraint is easy to enforce. (Just abort if we > use an emacs_env off the main thread.) > > > Would you really abort, or rather use the error handling functions? We > should be able to make the error values thread-local so that calling a > function from the wrong thread would be the equivalent of raising a > signal, giving the caller a chance to react. Otherwise the burden of > remembering the correct thread would be on the caller's side. If we abort, thread mismatch is a programming error, and we can omit optionally the check for performance. If we fail in some recoverable way, we have to perform the thread check every time, since it's now contractual. > > > typedef struct emacs_value_tag* emacs_value; > > > I think it's important that this is a pointer to a struct (for type > safety and size correctness) rather than just an arbitrary type. A typedef is exactly as typesafe. The question of whether to use a struct or a typedef is aesthetic. I strongly prefer a typedef, just like pthreads, and I believe that the people who advocate using structs directly are simply wrong. > typedef emacs_value (*emacs_subr)( > emacs_env* env, > int nargs, > emacs_value args[]); > > > Could we give this a void* data parameter for storing arbitrary user > data? This is common for callbacks in C interfaces and allows C++ users > to store C++ objects in the pointer. This can be implemented using > another save pointer. Yes, of course. > > > > emacs_value (*funcall)( > emacs_env* env, > emacs_value function, > int nargs, > emacs_value args[]); > > > Does function have to be a function object, or can it be a symbol? I.e. > is the user supposed to call symbol-function first? It'll have the same semantics as Ffuncall, so we'll be able to call a symbol or a function. > int64_t (*fixnum_to_int)( > emacs_env* env, > emacs_value value); > > emacs_value (*make_fixnum)( > emacs_env* env, > int64_t value); > > > What's the behavior of these functions if the source would not fit into > the result? Undefined behavior, abort(), raising a signal? I think we can do a range check fairly inexpensively, so just failing is probably fine. Code that ignores the possibility of failure will just abort later when it tries to misuse the API. If that's too expensive or error prone, we can just convert to an unspecified value when out of range (in practice, lopping off the extra bits). > Modules can use make_global_reference to allocate a global reference > (i.e., a GC root) for any emacs_value; modules must then free these > references explicitly. > > All routines (except make_global_reference) that return emacs_value > values return local references. It's up to modules to register > long-lived references explicitly. > > > In which cases would global references be necessary? Any time you want to hold onto a lisp value outside the dynamic extent of your emacs_env. > Like JNI, we can just declare that it's illegal to call all but a few > specially-marked functions (like global reference deregistration) with > a pending error. > > > What's the behavior if other functions are called? abort()? abort in check mode; unspecified when optimizing for performance. > > > If Lisp signals or throws, `funcall' returns NULL. > > > Hmm, with the current implementation emacs_value is just the same as > Lisp_Object, i.e. not a real pointer, so NULL doesn't have specific > semantics. Should it return Qnil instead and force the user to use > check_error? I thought we make Qnil equal zero. In any case, I *don't* like the idea of Lisp_Object being emacs_value. I'd much rather emacs_value be a pointer to a Lisp_Object, solving this problem completely. > 3) How exactly do we represent catch/throw values? > > > I've thought about this a bit, and I think it would be simplest to add a > new function env->set_throw and have get_error and check_error return an > enum { normal, signal, throw }. One could come up with something like > creating a list (error-kind error-tag error-value), but it looks like > the module implementation would create such lists only for the module > code to convert them back, so it's simpler to represent the two kinds of > non-local exits directly in the interface. I'm fine with a list; keep in mind that we'll need to handle OOM somehow, so I'd suggest an opaque type. > 4) Do we need to use int64_t for integers? > > > Maybe just intmax_t and a static check that that is larger than an Elisp > integer? Why make the behavior vary depending on what intmax_t is? At least int64_t is nice and explicit. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 9:10 ` Daniel Colascione @ 2015-10-04 9:41 ` Philipp Stephani 2015-10-04 17:48 ` Philipp Stephani ` (2 more replies) 0 siblings, 3 replies; 765+ messages in thread From: Philipp Stephani @ 2015-10-04 9:41 UTC (permalink / raw) To: Daniel Colascione, Eli Zaretskii Cc: Aurélien Aptel, stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 5174 bytes --] Daniel Colascione <dancol@dancol.org> schrieb am So., 4. Okt. 2015 um 11:10 Uhr: > On 10/04/2015 01:57 AM, Philipp Stephani wrote: > > Daniel Colascione <dancol@dancol.org <mailto:dancol@dancol.org>> schrieb > > am So., 15. Feb. 2015 um 21:21 Uhr: > > > > Here's a broad outline of what I have in mind. > > > > > > Thanks, that looks really good. Just a few minor issues that I > > encountered over the last couple of weeks. > > > > > > Thread-local environments > > ------------------------- > > > > The `get_environment' member lets us do anything else interesting. As > > in Java, environments are thread-local. We only support one thread > for > > the moment, so this constraint is easy to enforce. (Just abort if we > > use an emacs_env off the main thread.) > > > > > > Would you really abort, or rather use the error handling functions? We > > should be able to make the error values thread-local so that calling a > > function from the wrong thread would be the equivalent of raising a > > signal, giving the caller a chance to react. Otherwise the burden of > > remembering the correct thread would be on the caller's side. > > If we abort, thread mismatch is a programming error, and we can omit > optionally the check for performance. If we fail in some recoverable > way, we have to perform the thread check every time, since it's now > contractual. > OK. > > > > > > > typedef struct emacs_value_tag* emacs_value; > > > > > > I think it's important that this is a pointer to a struct (for type > > safety and size correctness) rather than just an arbitrary type. > > A typedef is exactly as typesafe. The question of whether to use a > struct or a typedef is aesthetic. I strongly prefer a typedef, just like > pthreads, and I believe that the people who advocate using structs > directly are simply wrong. > Ah, I'm not against the typedef, I'm just asking whether you would make it part of the API contract that it's a typedef of a struct pointer, or whether it can be any type. > > Modules can use make_global_reference to allocate a global reference > > (i.e., a GC root) for any emacs_value; modules must then free these > > references explicitly. > > > > All routines (except make_global_reference) that return emacs_value > > values return local references. It's up to modules to register > > long-lived references explicitly. > > > > > > In which cases would global references be necessary? > > Any time you want to hold onto a lisp value outside the dynamic extent > of your emacs_env. > Isn't the dynamic extent of the emacs_env the whole program, starting from the module initializer? > > > Like JNI, we can just declare that it's illegal to call all but a few > > specially-marked functions (like global reference deregistration) > with > > a pending error. > > > > > > What's the behavior if other functions are called? abort()? > > abort in check mode; unspecified when optimizing for performance. > OK, makes sense. Probably it should be abort() in all cases right now, the test should be really fast. > > > > > > > If Lisp signals or throws, `funcall' returns NULL. > > > > > > Hmm, with the current implementation emacs_value is just the same as > > Lisp_Object, i.e. not a real pointer, so NULL doesn't have specific > > semantics. Should it return Qnil instead and force the user to use > > check_error? > > I thought we make Qnil equal zero. In any case, I *don't* like the idea > of Lisp_Object being emacs_value. I'd much rather emacs_value be a > pointer to a Lisp_Object, solving this problem completely. > I agree with you, but that's how it's currently implemented. > > > 3) How exactly do we represent catch/throw values? > > > > > > I've thought about this a bit, and I think it would be simplest to add a > > new function env->set_throw and have get_error and check_error return an > > enum { normal, signal, throw }. One could come up with something like > > creating a list (error-kind error-tag error-value), but it looks like > > the module implementation would create such lists only for the module > > code to convert them back, so it's simpler to represent the two kinds of > > non-local exits directly in the interface. > > I'm fine with a list; keep in mind that we'll need to handle OOM > somehow, so I'd suggest an opaque type. > I think OOM is currently handled by doing the equivalent of (apply #'signal memory-signal-data) so it would be part of the normal signal handling. Using a list would be possible, but then the distinction between error tag and data could be removed from the module code. But I think the 'magic lists' idiom common in Emacs is more of an antipattern and we should try to avoid it in the module interface, thus the suggestion to use an enum. > > > 4) Do we need to use int64_t for integers? > > > > > > Maybe just intmax_t and a static check that that is larger than an Elisp > > integer? > > Why make the behavior vary depending on what intmax_t is? At least > int64_t is nice and explicit. > > True. The time when Emacs integers will be larger than 64 bits is probably far in the future. [-- Attachment #2: Type: text/html, Size: 7201 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 9:41 ` Philipp Stephani @ 2015-10-04 17:48 ` Philipp Stephani 2015-10-04 19:20 ` Paul Eggert 2015-10-04 19:34 ` Daniel Colascione 2 siblings, 0 replies; 765+ messages in thread From: Philipp Stephani @ 2015-10-04 17:48 UTC (permalink / raw) To: Daniel Colascione, Eli Zaretskii Cc: Aurélien Aptel, stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1669 bytes --] Philipp Stephani <p.stephani2@gmail.com> schrieb am So., 4. Okt. 2015 um 11:41 Uhr: > >> > 3) How exactly do we represent catch/throw values? >> > >> > >> > I've thought about this a bit, and I think it would be simplest to add a >> > new function env->set_throw and have get_error and check_error return an >> > enum { normal, signal, throw }. One could come up with something like >> > creating a list (error-kind error-tag error-value), but it looks like >> > the module implementation would create such lists only for the module >> > code to convert them back, so it's simpler to represent the two kinds of >> > non-local exits directly in the interface. >> >> I'm fine with a list; keep in mind that we'll need to handle OOM >> somehow, so I'd suggest an opaque type. >> > > I think OOM is currently handled by doing the equivalent of > > (apply #'signal memory-signal-data) > > so it would be part of the normal signal handling. Using a list would be > possible, but then the distinction between error tag and data could be > removed from the module code. But I think the 'magic lists' idiom common in > Emacs is more of an antipattern and we should try to avoid it in the module > interface, thus the suggestion to use an enum. > > I've amended the PR with basic handling of throw. It's treated as if it were at the top level, i.e. it generates a signal with symbol 'no-catch and data (tag value). There is currently no functionality available to "throw" from module code, and probably none is needed because "throw" is generally used as a local control flow mechanism, and modules can use the control flow mechanisms available in their languages instead. [-- Attachment #2: Type: text/html, Size: 2406 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 9:41 ` Philipp Stephani 2015-10-04 17:48 ` Philipp Stephani @ 2015-10-04 19:20 ` Paul Eggert 2015-10-04 19:25 ` Daniel Colascione 2015-10-04 19:34 ` Daniel Colascione 2 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-10-04 19:20 UTC (permalink / raw) To: Philipp Stephani, Daniel Colascione, Eli Zaretskii Cc: Aurélien Aptel, stephen_leake, emacs-devel Philipp Stephani wrote: >> Why make the behavior vary depending on what intmax_t is? At least >> >int64_t is nice and explicit. >> > >> > > True. The time when Emacs integers will be larger than 64 bits is probably > far in the future. No, I've already been toying with integers wider than 64 bits in my own private copy of emacs. It's not ready for publication yet, but you should be assuming that bignums are possible and even desirable, and foreign-function APIs should not preclude their use. Also, the C standard does not require support for int64_t. It's OK to use int64_t in platform-specific code where you know the platform has int64_t, but otherwise it's better to avoid it. The Emacs source code largely avoids int64_t now, and there's no good reason to require it here. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 19:20 ` Paul Eggert @ 2015-10-04 19:25 ` Daniel Colascione 2015-10-04 19:55 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-10-04 19:25 UTC (permalink / raw) To: Paul Eggert, Philipp Stephani, Eli Zaretskii Cc: Aurélien Aptel, stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1420 bytes --] On 10/04/2015 12:20 PM, Paul Eggert wrote: > Philipp Stephani wrote: >>> Why make the behavior vary depending on what intmax_t is? At least >>> >int64_t is nice and explicit. >>> > >>> > >> True. The time when Emacs integers will be larger than 64 bits is >> probably >> far in the future. > > No, I've already been toying with integers wider than 64 bits in my own > private copy of emacs. It's not ready for publication yet, but you > should be assuming that bignums are possible and even desirable, and > foreign-function APIs should not preclude their use. First of all, that's awesome. Anyway, bignums may be larger than 64-bits, but fixnums never will be. Nor will C ever have an integer type wide enough to accommodate all possible numeric types. I'm happy with letting C use int64_t for fixnums and describing larger numbers through strings or GMP bindings or something. > Also, the C standard does not require support for int64_t. It's OK to > use int64_t in platform-specific code where you know the platform has > int64_t, but otherwise it's better to avoid it. The Emacs source code > largely avoids int64_t now, and there's no good reason to require it here. We already require C99. Any compiler modern enough to support C99 also supports synthesizing 64-bit integers from whatever the platform makes available. I am strongly opposed to catering to obsolete systems. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 19:25 ` Daniel Colascione @ 2015-10-04 19:55 ` Paul Eggert 2015-10-04 19:57 ` Daniel Colascione 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-10-04 19:55 UTC (permalink / raw) To: Daniel Colascione, Philipp Stephani, Eli Zaretskii Cc: Aurélien Aptel, stephen_leake, emacs-devel Daniel Colascione wrote: > Any compiler modern enough to support C99 also > supports synthesizing 64-bit integers from whatever the platform makes > available. No, all that C99 requires is support for integers *at least* 64 bits. C99 does not require support for int64_t, i.e., integers that are *exactly* 64 bits. If we need a type that is at least 64 bits wide, we can use int_fast64_t or int_least64_t. These types are required by C99 and will work even on the rare platforms that lack native 64-bit words. But really, I'm hoping we can avoid the *int*64* stuff. What's the point of putting a 64-bit limit on an API that is supposed to be long-lived and portable? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 19:55 ` Paul Eggert @ 2015-10-04 19:57 ` Daniel Colascione 2015-10-04 20:19 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-10-04 19:57 UTC (permalink / raw) To: Paul Eggert, Philipp Stephani, Eli Zaretskii Cc: Aurélien Aptel, stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 865 bytes --] On 10/04/2015 12:55 PM, Paul Eggert wrote: > Daniel Colascione wrote: >> Any compiler modern enough to support C99 also >> supports synthesizing 64-bit integers from whatever the platform makes >> available. > > No, all that C99 requires is support for integers *at least* 64 bits. > C99 does not require support for int64_t, i.e., integers that are > *exactly* 64 bits. > > If we need a type that is at least 64 bits wide, we can use int_fast64_t > or int_least64_t. These types are required by C99 and will work even on > the rare platforms that lack native 64-bit words. But really, I'm > hoping we can avoid the *int*64* stuff. What's the point of putting a > 64-bit limit on an API that is supposed to be long-lived and portable? Can you really imagine a general-purpose machine with 128-bit words? Why would you build such a thing? [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 19:57 ` Daniel Colascione @ 2015-10-04 20:19 ` Paul Eggert 0 siblings, 0 replies; 765+ messages in thread From: Paul Eggert @ 2015-10-04 20:19 UTC (permalink / raw) To: Daniel Colascione, Philipp Stephani, Eli Zaretskii Cc: Aurélien Aptel, stephen_leake, emacs-devel Daniel Colascione wrote: > Can you really imagine a general-purpose machine with 128-bit words? I don't have to imagine it. I have one on my desk right now, running Ubuntu 15.04 on a Xeon E3-1225. If I take this program: __int128 mulbig (long a, long b) { __int128 aa = a; return aa * b; } and compile it with gcc -O2, I get the following machine instructions: mulbig: movq %rdi, %rax imulq %rsi ret and this yields a 128-bit value with the mathematically-correct answer (integer overflow is not possible for this example). Admittedly my desktop doesn't support 128-bit words as well as I'd like. But the support should be good enough for Emacs (of course, it should be enabled only on platforms that have it). ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 9:41 ` Philipp Stephani 2015-10-04 17:48 ` Philipp Stephani 2015-10-04 19:20 ` Paul Eggert @ 2015-10-04 19:34 ` Daniel Colascione 2015-10-04 19:47 ` Philipp Stephani 2015-10-14 22:34 ` Philipp Stephani 2 siblings, 2 replies; 765+ messages in thread From: Daniel Colascione @ 2015-10-04 19:34 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii Cc: Aurélien Aptel, stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 2491 bytes --] On 10/04/2015 02:41 AM, Philipp Stephani wrote: > > > > > > typedef struct emacs_value_tag* emacs_value; > > > > > > I think it's important that this is a pointer to a struct (for type > > safety and size correctness) rather than just an arbitrary type. > > A typedef is exactly as typesafe. The question of whether to use a > struct or a typedef is aesthetic. I strongly prefer a typedef, just like > pthreads, and I believe that the people who advocate using structs > directly are simply wrong. > > > Ah, I'm not against the typedef, I'm just asking whether you would make > it part of the API contract that it's a typedef of a struct pointer, or > whether it can be any type. The problem with defining it as a pointer type is that NULL is now the invalid sentinel value, which seems incompatible with both making this thing literally a Lisp_Object and Qnil having all zero bits. That's why I strongly prefer making emacs_value a _pointer_ to a Lisp_Object, where we store the Lisp_Object in an array owned by the emacs_env. This way, allocating local values is very cheap. > > Modules can use make_global_reference to allocate a global > reference > > (i.e., a GC root) for any emacs_value; modules must then free > these > > references explicitly. > > > > All routines (except make_global_reference) that return > emacs_value > > values return local references. It's up to modules to register > > long-lived references explicitly. > > > > > > In which cases would global references be necessary? > > Any time you want to hold onto a lisp value outside the dynamic extent > of your emacs_env. > > > Isn't the dynamic extent of the emacs_env the whole program, starting > from the module initializer? Not necessarily. An emacs_env is valid only for the current call into module code on the current thread. So if we call module-function-1, wait for it to return, then call module-function-2, the two calls can have different environments, and using local references from one might not be valid on the other. (This approach opens up very important optimizations in JNI, and it'd be good for us to use the same approach.) A global reference is just an emacs_env in a heap-allocated object we register as a GC root. (To answer the question another way: global references are GC roots.) [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 19:34 ` Daniel Colascione @ 2015-10-04 19:47 ` Philipp Stephani 2015-10-04 21:12 ` Aurélien Aptel 2015-10-14 22:34 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-10-04 19:47 UTC (permalink / raw) To: Daniel Colascione, Eli Zaretskii Cc: Aurélien Aptel, stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 3209 bytes --] Daniel Colascione <dancol@dancol.org> schrieb am So., 4. Okt. 2015 um 21:34 Uhr: > On 10/04/2015 02:41 AM, Philipp Stephani wrote: > > > > > > > > > typedef struct emacs_value_tag* emacs_value; > > > > > > > > > I think it's important that this is a pointer to a struct (for type > > > safety and size correctness) rather than just an arbitrary type. > > > > A typedef is exactly as typesafe. The question of whether to use a > > struct or a typedef is aesthetic. I strongly prefer a typedef, just > like > > pthreads, and I believe that the people who advocate using structs > > directly are simply wrong. > > > > > > Ah, I'm not against the typedef, I'm just asking whether you would make > > it part of the API contract that it's a typedef of a struct pointer, or > > whether it can be any type. > > The problem with defining it as a pointer type is that NULL is now the > invalid sentinel value, which seems incompatible with both making this > thing literally a Lisp_Object and Qnil having all zero bits. > > That's why I strongly prefer making emacs_value a _pointer_ to a > Lisp_Object, where we store the Lisp_Object in an array owned by the > emacs_env. This way, allocating local values is very cheap. > Aurélien, is that something you agree with and could implement? > > > > Modules can use make_global_reference to allocate a global > > reference > > > (i.e., a GC root) for any emacs_value; modules must then free > > these > > > references explicitly. > > > > > > All routines (except make_global_reference) that return > > emacs_value > > > values return local references. It's up to modules to register > > > long-lived references explicitly. > > > > > > > > > In which cases would global references be necessary? > > > > Any time you want to hold onto a lisp value outside the dynamic > extent > > of your emacs_env. > > > > > > Isn't the dynamic extent of the emacs_env the whole program, starting > > from the module initializer? > > Not necessarily. An emacs_env is valid only for the current call into > module code on the current thread. So if we call module-function-1, wait > for it to return, then call module-function-2, the two calls can have > different environments, and using local references from one might not be > valid on the other. (This approach opens up very important optimizations > in JNI, and it'd be good for us to use the same approach.) A global > reference is just an emacs_env in a heap-allocated object we register as > a GC root. > > (To answer the question another way: global references are GC roots.) > > OK, IIUC the examples in Aurélien's branch are then invalid because they store the result of intern("nil") in a static variable, right? One more thing: is equality of two emacs_value objects defined? Right now it's `eq', but that's probably also an implementation detail. If equality is not defined as `eq', we also need a "null" function in the environment that returns bool, otherwise there would be no way to implement conditions. [-- Attachment #2: Type: text/html, Size: 4085 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 19:47 ` Philipp Stephani @ 2015-10-04 21:12 ` Aurélien Aptel 2015-10-05 5:50 ` Eli Zaretskii 2015-10-14 22:25 ` Philipp Stephani 0 siblings, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-10-04 21:12 UTC (permalink / raw) To: Philipp Stephani Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions On Sun, Oct 4, 2015 at 9:47 PM, Philipp Stephani <p.stephani2@gmail.com> wrote: > Aurélien, is that something you agree with and could implement? I'm not sure I understood what you wanted.. I've commited this, but it assumes Lisp_Object are the same size as pointers... commit 4c2813950d14fa2348e30ee94a4f3b022263e36d Author: Aurélien Aptel <aurelien.aptel@gmail.com> Date: Sun Oct 4 23:04:56 2015 +0200 use opaque struct emacs_value_tag instead of void* for emacs_value. diff --git a/src/emacs_module.h b/src/emacs_module.h index c5ec347..b055547 100644 --- a/src/emacs_module.h +++ b/src/emacs_module.h @@ -27,7 +27,7 @@ /* Current environement */ typedef struct emacs_env_25 emacs_env; -typedef void* emacs_value; +typedef struct emacs_value_tag* emacs_value; enum emacs_type { EMACS_FIXNUM, diff --git a/src/module.c b/src/module.c index 9bbb832..ab058bb 100644 --- a/src/module.c +++ b/src/module.c @@ -24,6 +24,8 @@ #include "dynlib.h" #include "coding.h" +struct emacs_value_tag { Lisp_Object v; }; + void syms_of_module (void); static struct emacs_runtime* module_get_runtime (void); static emacs_env* module_get_environment (struct emacs_runtime *ert); ^ permalink raw reply related [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 21:12 ` Aurélien Aptel @ 2015-10-05 5:50 ` Eli Zaretskii 2015-10-14 22:28 ` Philipp Stephani 2015-10-14 22:25 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-10-05 5:50 UTC (permalink / raw) To: Aurélien Aptel; +Cc: p.stephani2, dancol, stephen_leake, emacs-devel > Date: Sun, 4 Oct 2015 23:12:16 +0200 > From: Aurélien Aptel <aurelien.aptel+emacs@gmail.com> > Cc: Daniel Colascione <dancol@dancol.org>, Eli Zaretskii <eliz@gnu.org>, > Stephen Leake <stephen_leake@stephe-leake.org>, > Emacs development discussions <emacs-devel@gnu.org> > > On Sun, Oct 4, 2015 at 9:47 PM, Philipp Stephani <p.stephani2@gmail.com> wrote: > > Aurélien, is that something you agree with and could implement? > > I'm not sure I understood what you wanted.. I've commited this, but it > assumes Lisp_Object are the same size as pointers... That assumption is false in an Emacs built --with-wide-int. If you need to wrap a pointer in a Lisp_Object, we have XIL and XLI macros for that. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-05 5:50 ` Eli Zaretskii @ 2015-10-14 22:28 ` Philipp Stephani 2015-10-15 2:43 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-10-14 22:28 UTC (permalink / raw) To: Eli Zaretskii, Aurélien Aptel; +Cc: dancol, stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1055 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am Mo., 5. Okt. 2015 um 07:50 Uhr: > > Date: Sun, 4 Oct 2015 23:12:16 +0200 > > From: Aurélien Aptel <aurelien.aptel+emacs@gmail.com> > > Cc: Daniel Colascione <dancol@dancol.org>, Eli Zaretskii <eliz@gnu.org>, > > Stephen Leake <stephen_leake@stephe-leake.org>, > > Emacs development discussions <emacs-devel@gnu.org> > > > > On Sun, Oct 4, 2015 at 9:47 PM, Philipp Stephani <p.stephani2@gmail.com> > wrote: > > > Aurélien, is that something you agree with and could implement? > > > > I'm not sure I understood what you wanted.. I've commited this, but it > > assumes Lisp_Object are the same size as pointers... > > That assumption is false in an Emacs built --with-wide-int. > > If you need to wrap a pointer in a Lisp_Object, we have XIL and XLI > macros for that. > These are no-ops in my version of lisp.h: # define lisp_h_XLI(o) (o) # define lisp_h_XIL(i) (i) Unless I'm misunderstanding something, these macros can't be used to wrap pointers in the general case. [-- Attachment #2: Type: text/html, Size: 1862 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-14 22:28 ` Philipp Stephani @ 2015-10-15 2:43 ` Eli Zaretskii 2015-10-15 7:00 ` Andreas Schwab 2015-10-15 23:07 ` Philipp Stephani 0 siblings, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-10-15 2:43 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, dancol, stephen_leake, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Wed, 14 Oct 2015 22:28:01 +0000 > Cc: dancol@dancol.org, stephen_leake@stephe-leake.org, emacs-devel@gnu.org > > > I'm not sure I understood what you wanted.. I've commited this, but it > > assumes Lisp_Object are the same size as pointers... > > That assumption is false in an Emacs built --with-wide-int. > > If you need to wrap a pointer in a Lisp_Object, we have XIL and XLI > macros for that. > > > These are no-ops in my version of lisp.h: > > # define lisp_h_XLI(o) (o) > # define lisp_h_XIL(i) (i) > > Unless I'm misunderstanding something, these macros can't be used to wrap > pointers in the general case. We do that all the time, so I don't understand why you understand that. Please elaborate. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 2:43 ` Eli Zaretskii @ 2015-10-15 7:00 ` Andreas Schwab 2015-10-15 10:13 ` Aurélien Aptel 2015-10-15 15:38 ` Eli Zaretskii 2015-10-15 23:07 ` Philipp Stephani 1 sibling, 2 replies; 765+ messages in thread From: Andreas Schwab @ 2015-10-15 7:00 UTC (permalink / raw) To: Eli Zaretskii Cc: aurelien.aptel+emacs, Philipp Stephani, dancol, stephen_leake, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Philipp Stephani <p.stephani2@gmail.com> >> Date: Wed, 14 Oct 2015 22:28:01 +0000 >> Cc: dancol@dancol.org, stephen_leake@stephe-leake.org, emacs-devel@gnu.org >> >> > I'm not sure I understood what you wanted.. I've commited this, but it >> > assumes Lisp_Object are the same size as pointers... >> >> That assumption is false in an Emacs built --with-wide-int. >> >> If you need to wrap a pointer in a Lisp_Object, we have XIL and XLI >> macros for that. >> >> >> These are no-ops in my version of lisp.h: >> >> # define lisp_h_XLI(o) (o) >> # define lisp_h_XIL(i) (i) >> >> Unless I'm misunderstanding something, these macros can't be used to wrap >> pointers in the general case. > > We do that all the time, so I don't understand why you understand > that. Please elaborate. You can only use them for pointers that are known to fit in the range of Lisp_Int, ie. all tag bits clear. This is true for all lisp object pointers (obviously), but not for other pointers. For boxing arbitrary pointers we have Lisp_Save_Value. Andreas. -- Andreas Schwab, SUSE Labs, schwab@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different." ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 7:00 ` Andreas Schwab @ 2015-10-15 10:13 ` Aurélien Aptel 2015-10-15 15:38 ` Eli Zaretskii 1 sibling, 0 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-10-15 10:13 UTC (permalink / raw) To: Andreas Schwab Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Philipp Stephani, Emacs development discussions On Thu, Oct 15, 2015 at 9:00 AM, Andreas Schwab <schwab@suse.de> wrote: > You can only use them for pointers that are known to fit in the range of > Lisp_Int, ie. all tag bits clear. This is true for all lisp object > pointers (obviously), but not for other pointers. For boxing arbitrary > pointers we have Lisp_Save_Value. I've used Save_Value for storing a module function context but a new type has to be defined for module pointers in order to handle user-provided finalizers. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 7:00 ` Andreas Schwab 2015-10-15 10:13 ` Aurélien Aptel @ 2015-10-15 15:38 ` Eli Zaretskii 2015-10-15 15:56 ` Andreas Schwab 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-10-15 15:38 UTC (permalink / raw) To: Andreas Schwab Cc: aurelien.aptel+emacs, p.stephani2, dancol, stephen_leake, emacs-devel > From: Andreas Schwab <schwab@suse.de> > Cc: Philipp Stephani <p.stephani2@gmail.com>, aurelien.aptel+emacs@gmail.com, dancol@dancol.org, stephen_leake@stephe-leake.org, emacs-devel@gnu.org > Date: Thu, 15 Oct 2015 09:00:35 +0200 > > >> If you need to wrap a pointer in a Lisp_Object, we have XIL and XLI > >> macros for that. > >> > >> > >> These are no-ops in my version of lisp.h: > >> > >> # define lisp_h_XLI(o) (o) > >> # define lisp_h_XIL(i) (i) > >> > >> Unless I'm misunderstanding something, these macros can't be used to wrap > >> pointers in the general case. > > > > We do that all the time, so I don't understand why you understand > > that. Please elaborate. > > You can only use them for pointers that are known to fit in the range of > Lisp_Int, ie. all tag bits clear. This is true for all lisp object > pointers (obviously), but not for other pointers. For boxing arbitrary > pointers we have Lisp_Save_Value. Right, for pointers to simple data types, like 'char', 'short', 'int', etc., one needs to use Lisp_Save_Value. For pointers to struct's, XLI and XIL will do the job on the supported platforms. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 15:38 ` Eli Zaretskii @ 2015-10-15 15:56 ` Andreas Schwab 2015-10-15 16:01 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Andreas Schwab @ 2015-10-15 15:56 UTC (permalink / raw) To: Eli Zaretskii Cc: aurelien.aptel+emacs, p.stephani2, dancol, stephen_leake, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > Right, for pointers to simple data types, like 'char', 'short', 'int', > etc., one needs to use Lisp_Save_Value. For pointers to struct's, XLI > and XIL will do the job on the supported platforms. No, it doesn't. Structures are not special in any way. Andreas. -- Andreas Schwab, SUSE Labs, schwab@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different." ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 15:56 ` Andreas Schwab @ 2015-10-15 16:01 ` Eli Zaretskii 2015-10-15 16:07 ` Andreas Schwab 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-10-15 16:01 UTC (permalink / raw) To: Andreas Schwab Cc: aurelien.aptel+emacs, p.stephani2, dancol, stephen_leake, emacs-devel > From: Andreas Schwab <schwab@suse.de> > Cc: p.stephani2@gmail.com, aurelien.aptel+emacs@gmail.com, dancol@dancol.org, stephen_leake@stephe-leake.org, emacs-devel@gnu.org > Date: Thu, 15 Oct 2015 17:56:36 +0200 > > Eli Zaretskii <eliz@gnu.org> writes: > > > Right, for pointers to simple data types, like 'char', 'short', 'int', > > etc., one needs to use Lisp_Save_Value. For pointers to struct's, XLI > > and XIL will do the job on the supported platforms. > > No, it doesn't. It does in Emacs. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 16:01 ` Eli Zaretskii @ 2015-10-15 16:07 ` Andreas Schwab 2015-10-15 16:31 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Andreas Schwab @ 2015-10-15 16:07 UTC (permalink / raw) To: Eli Zaretskii Cc: aurelien.aptel+emacs, p.stephani2, dancol, stephen_leake, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Andreas Schwab <schwab@suse.de> >> Cc: p.stephani2@gmail.com, aurelien.aptel+emacs@gmail.com, dancol@dancol.org, stephen_leake@stephe-leake.org, emacs-devel@gnu.org >> Date: Thu, 15 Oct 2015 17:56:36 +0200 >> >> Eli Zaretskii <eliz@gnu.org> writes: >> >> > Right, for pointers to simple data types, like 'char', 'short', 'int', >> > etc., one needs to use Lisp_Save_Value. For pointers to struct's, XLI >> > and XIL will do the job on the supported platforms. >> >> No, it doesn't. > > It does in Emacs. In which way? Andreas. -- Andreas Schwab, SUSE Labs, schwab@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different." ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 16:07 ` Andreas Schwab @ 2015-10-15 16:31 ` Eli Zaretskii 2015-10-15 17:03 ` Andreas Schwab 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-10-15 16:31 UTC (permalink / raw) To: Andreas Schwab Cc: aurelien.aptel+emacs, p.stephani2, dancol, stephen_leake, emacs-devel > From: Andreas Schwab <schwab@suse.de> > Cc: p.stephani2@gmail.com, aurelien.aptel+emacs@gmail.com, dancol@dancol.org, stephen_leake@stephe-leake.org, emacs-devel@gnu.org > Date: Thu, 15 Oct 2015 18:07:03 +0200 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> From: Andreas Schwab <schwab@suse.de> > >> Cc: p.stephani2@gmail.com, aurelien.aptel+emacs@gmail.com, dancol@dancol.org, stephen_leake@stephe-leake.org, emacs-devel@gnu.org > >> Date: Thu, 15 Oct 2015 17:56:36 +0200 > >> > >> Eli Zaretskii <eliz@gnu.org> writes: > >> > >> > Right, for pointers to simple data types, like 'char', 'short', 'int', > >> > etc., one needs to use Lisp_Save_Value. For pointers to struct's, XLI > >> > and XIL will do the job on the supported platforms. > >> > >> No, it doesn't. > > > > It does in Emacs. > > In which way? In the Right Way. The bits that need to be reset are reset. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 16:31 ` Eli Zaretskii @ 2015-10-15 17:03 ` Andreas Schwab 2015-10-15 17:07 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Andreas Schwab @ 2015-10-15 17:03 UTC (permalink / raw) To: Eli Zaretskii Cc: aurelien.aptel+emacs, p.stephani2, dancol, stephen_leake, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Andreas Schwab <schwab@suse.de> >> Cc: p.stephani2@gmail.com, aurelien.aptel+emacs@gmail.com, dancol@dancol.org, stephen_leake@stephe-leake.org, emacs-devel@gnu.org >> Date: Thu, 15 Oct 2015 18:07:03 +0200 >> >> Eli Zaretskii <eliz@gnu.org> writes: >> >> >> From: Andreas Schwab <schwab@suse.de> >> >> Cc: p.stephani2@gmail.com, aurelien.aptel+emacs@gmail.com, dancol@dancol.org, stephen_leake@stephe-leake.org, emacs-devel@gnu.org >> >> Date: Thu, 15 Oct 2015 17:56:36 +0200 >> >> >> >> Eli Zaretskii <eliz@gnu.org> writes: >> >> >> >> > Right, for pointers to simple data types, like 'char', 'short', 'int', >> >> > etc., one needs to use Lisp_Save_Value. For pointers to struct's, XLI >> >> > and XIL will do the job on the supported platforms. >> >> >> >> No, it doesn't. >> > >> > It does in Emacs. >> >> In which way? > > In the Right Way. The bits that need to be reset are reset. This is not guaranteed. Andreas. -- Andreas Schwab, SUSE Labs, schwab@suse.de GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE 1748 E4D4 88E3 0EEA B9D7 "And now for something completely different." ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 17:03 ` Andreas Schwab @ 2015-10-15 17:07 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-10-15 17:07 UTC (permalink / raw) To: Andreas Schwab Cc: aurelien.aptel+emacs, p.stephani2, dancol, stephen_leake, emacs-devel > From: Andreas Schwab <schwab@suse.de> > Cc: aurelien.aptel+emacs@gmail.com, p.stephani2@gmail.com, dancol@dancol.org, stephen_leake@stephe-leake.org, emacs-devel@gnu.org > Date: Thu, 15 Oct 2015 19:03:49 +0200 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> From: Andreas Schwab <schwab@suse.de> > >> Cc: p.stephani2@gmail.com, aurelien.aptel+emacs@gmail.com, dancol@dancol.org, stephen_leake@stephe-leake.org, emacs-devel@gnu.org > >> Date: Thu, 15 Oct 2015 18:07:03 +0200 > >> > >> Eli Zaretskii <eliz@gnu.org> writes: > >> > >> >> From: Andreas Schwab <schwab@suse.de> > >> >> Cc: p.stephani2@gmail.com, aurelien.aptel+emacs@gmail.com, dancol@dancol.org, stephen_leake@stephe-leake.org, emacs-devel@gnu.org > >> >> Date: Thu, 15 Oct 2015 17:56:36 +0200 > >> >> > >> >> Eli Zaretskii <eliz@gnu.org> writes: > >> >> > >> >> > Right, for pointers to simple data types, like 'char', 'short', 'int', > >> >> > etc., one needs to use Lisp_Save_Value. For pointers to struct's, XLI > >> >> > and XIL will do the job on the supported platforms. > >> >> > >> >> No, it doesn't. > >> > > >> > It does in Emacs. > >> > >> In which way? > > > > In the Right Way. The bits that need to be reset are reset. > > This is not guaranteed. I never saw it fail to work on any modern platform. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 2:43 ` Eli Zaretskii 2015-10-15 7:00 ` Andreas Schwab @ 2015-10-15 23:07 ` Philipp Stephani 2015-10-16 6:49 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-10-15 23:07 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, dancol, stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 999 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am Do., 15. Okt. 2015 um 04:44 Uhr: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Wed, 14 Oct 2015 22:28:01 +0000 > > Cc: dancol@dancol.org, stephen_leake@stephe-leake.org, > emacs-devel@gnu.org > > > > > I'm not sure I understood what you wanted.. I've commited this, > but it > > > assumes Lisp_Object are the same size as pointers... > > > > That assumption is false in an Emacs built --with-wide-int. > > > > If you need to wrap a pointer in a Lisp_Object, we have XIL and XLI > > macros for that. > > > > > > These are no-ops in my version of lisp.h: > > > > # define lisp_h_XLI(o) (o) > > # define lisp_h_XIL(i) (i) > > > > Unless I'm misunderstanding something, these macros can't be used to wrap > > pointers in the general case. > > We do that all the time, so I don't understand why you understand > that. Please elaborate. > > I got it backwards: we need to wrap Lisp_Objects in pointers, not the other way round. [-- Attachment #2: Type: text/html, Size: 1680 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 23:07 ` Philipp Stephani @ 2015-10-16 6:49 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-10-16 6:49 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, dancol, stephen_leake, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Thu, 15 Oct 2015 23:07:41 +0000 > Cc: aurelien.aptel+emacs@gmail.com, dancol@dancol.org, > stephen_leake@stephe-leake.org, emacs-devel@gnu.org > > > # define lisp_h_XLI(o) (o) > > # define lisp_h_XIL(i) (i) > > > > Unless I'm misunderstanding something, these macros can't be used to wrap > > pointers in the general case. > > We do that all the time, so I don't understand why you understand > that. Please elaborate. > > I got it backwards: we need to wrap Lisp_Objects in pointers, not the other way > round. That you cannot do portably. So in that case, I suggest to use a pointer to the Lisp object instead. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 21:12 ` Aurélien Aptel 2015-10-05 5:50 ` Eli Zaretskii @ 2015-10-14 22:25 ` Philipp Stephani 2015-10-14 23:48 ` Aurélien Aptel 1 sibling, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-10-14 22:25 UTC (permalink / raw) To: Aurélien Aptel Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 1964 bytes --] Aurélien Aptel <aurelien.aptel+emacs@gmail.com> schrieb am So., 4. Okt. 2015 um 23:12 Uhr: > On Sun, Oct 4, 2015 at 9:47 PM, Philipp Stephani <p.stephani2@gmail.com> > wrote: > > Aurélien, is that something you agree with and could implement? > > I'm not sure I understood what you wanted.. I've commited this, but it > assumes Lisp_Object are the same size as pointers... > > commit 4c2813950d14fa2348e30ee94a4f3b022263e36d > Author: Aurélien Aptel <aurelien.aptel@gmail.com> > Date: Sun Oct 4 23:04:56 2015 +0200 > > use opaque struct emacs_value_tag instead of void* for emacs_value. > > diff --git a/src/emacs_module.h b/src/emacs_module.h > index c5ec347..b055547 100644 > --- a/src/emacs_module.h > +++ b/src/emacs_module.h > @@ -27,7 +27,7 @@ > > /* Current environement */ > typedef struct emacs_env_25 emacs_env; > -typedef void* emacs_value; > +typedef struct emacs_value_tag* emacs_value; > > enum emacs_type { > EMACS_FIXNUM, > diff --git a/src/module.c b/src/module.c > index 9bbb832..ab058bb 100644 > --- a/src/module.c > +++ b/src/module.c > @@ -24,6 +24,8 @@ > #include "dynlib.h" > #include "coding.h" > > +struct emacs_value_tag { Lisp_Object v; }; > + > void syms_of_module (void); > static struct emacs_runtime* module_get_runtime (void); > static emacs_env* module_get_environment (struct emacs_runtime *ert); > This is good (thanks!), but still assumes that sizeof(Lisp_Object) <= sizeof(void*) and that (Lisp_Object)((void *)0) is never a valid Lisp object, both of which are not provably true. To implement Daniel's approach you'll also have to change: static Lisp_Object value_to_lisp (emacs_value value) { return value->v; } static emacs_value lisp_to_value (Lisp_Object object) { emacs_value v = (emacs_value) malloc(sizeof v); // The allocation needs to be smarter, this example leaks memory. if (!v) return 0; v->v = object; return v; } [-- Attachment #2: Type: text/html, Size: 2648 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-14 22:25 ` Philipp Stephani @ 2015-10-14 23:48 ` Aurélien Aptel 2015-10-15 0:25 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-10-14 23:48 UTC (permalink / raw) To: Philipp Stephani Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions On Thu, Oct 15, 2015 at 12:25 AM, Philipp Stephani <p.stephani2@gmail.com> wrote: > static Lisp_Object value_to_lisp (emacs_value value) { > return value->v; > } > > static emacs_value lisp_to_value (Lisp_Object object) { > emacs_value v = (emacs_value) malloc(sizeof v); > // The allocation needs to be smarter, this example leaks memory. > if (!v) return 0; > v->v = object; > return v; > } I'm not a big fan of a dynamically allocating memory for each conversion, it's too expensive. Daniel solution seems more manageable. By the way, I've merged your tls-errors branch in mine. But the API doesn't have an unsafe funcall iiuc. That's fine with me but Stefan was insistent on that. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-14 23:48 ` Aurélien Aptel @ 2015-10-15 0:25 ` Philipp Stephani 2015-10-15 10:44 ` Aurélien Aptel 2015-10-15 23:15 ` Philipp Stephani 0 siblings, 2 replies; 765+ messages in thread From: Philipp Stephani @ 2015-10-15 0:25 UTC (permalink / raw) To: Aurélien Aptel Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 1181 bytes --] Aurélien Aptel <aurelien.aptel+emacs@gmail.com> schrieb am Do., 15. Okt. 2015 um 01:48 Uhr: > On Thu, Oct 15, 2015 at 12:25 AM, Philipp Stephani > <p.stephani2@gmail.com> wrote: > > static Lisp_Object value_to_lisp (emacs_value value) { > > return value->v; > > } > > > > static emacs_value lisp_to_value (Lisp_Object object) { > > emacs_value v = (emacs_value) malloc(sizeof v); > > // The allocation needs to be smarter, this example leaks memory. > > if (!v) return 0; > > v->v = object; > > return v; > > } > > I'm not a big fan of a dynamically allocating memory for each > conversion, it's too expensive. Daniel solution seems more manageable. > Agreed. I've implemented Daniel's suggestion on the tls-error branch, it seems to work fine (but note that environments are now no longer global, so storing away emacs_values without global references now will lead to undefined behavior). > > By the way, I've merged your tls-errors branch in mine. Cool, thanks! > But the API > doesn't have an unsafe funcall iiuc. That's fine with me but Stefan > was insistent on that. > Let's see what will get accepted upstream. [-- Attachment #2: Type: text/html, Size: 1929 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 0:25 ` Philipp Stephani @ 2015-10-15 10:44 ` Aurélien Aptel 2015-10-15 15:41 ` Eli Zaretskii 2015-10-15 23:11 ` Dynamic loading progress Philipp Stephani 2015-10-15 23:15 ` Philipp Stephani 1 sibling, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-10-15 10:44 UTC (permalink / raw) To: Philipp Stephani Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions On Thu, Oct 15, 2015 at 2:25 AM, Philipp Stephani <p.stephani2@gmail.com> wrote: > Agreed. I've implemented Daniel's suggestion on the tls-error branch, it > seems to work fine (but note that environments are now no longer global, so > storing away emacs_values without global references now will lead to > undefined behavior). Yeah I just realized that. The nice thing with just casting is its the same memory object and the stack-scanning GC just works. Having the GC is nice... Again, IIUC, the only problem is on 32bit with wide-int, which is off by default. > Let's see what will get accepted upstream. That's sneaky... but this is how the free software world works I guess... ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 10:44 ` Aurélien Aptel @ 2015-10-15 15:41 ` Eli Zaretskii 2015-10-16 0:55 ` Juanma Barranquero 2015-10-15 23:11 ` Dynamic loading progress Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-10-15 15:41 UTC (permalink / raw) To: Aurélien Aptel; +Cc: p.stephani2, dancol, stephen_leake, emacs-devel > Date: Thu, 15 Oct 2015 12:44:00 +0200 > From: Aurélien Aptel <aurelien.aptel+emacs@gmail.com> > Cc: Daniel Colascione <dancol@dancol.org>, Eli Zaretskii <eliz@gnu.org>, > Stephen Leake <stephen_leake@stephe-leake.org>, > Emacs development discussions <emacs-devel@gnu.org> > > Again, IIUC, the only problem is on 32bit with wide-int, which is off > by default. Please don't assume that --with-wide-int is some rare marginal use case. I configure Emacs with it all the time, and intend to suggest that 32-bit builds at least on MS-Windows always use it. So I think we should have that use case covered, if we want the dynamic loading hit the streets. Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 15:41 ` Eli Zaretskii @ 2015-10-16 0:55 ` Juanma Barranquero 2015-10-16 5:42 ` martin rudalics 2015-10-16 7:09 ` Making --with-wide-int the default (was: Dynamic loading progress) Eli Zaretskii 0 siblings, 2 replies; 765+ messages in thread From: Juanma Barranquero @ 2015-10-16 0:55 UTC (permalink / raw) To: Eli Zaretskii Cc: Aurélien Aptel, p.stephani2, Daniel Colascione, Stephen Leake, Emacs developers [-- Attachment #1: Type: text/plain, Size: 347 bytes --] On Thu, Oct 15, 2015 at 5:41 PM, Eli Zaretskii <eliz@gnu.org> wrote: > Please don't assume that --with-wide-int is some rare marginal use > case. I configure Emacs with it all the time, and intend to suggest > that 32-bit builds at least on MS-Windows always use it. Why isn't it the default, then (for 32-bit builds)? Are there any downsides? [-- Attachment #2: Type: text/html, Size: 482 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-16 0:55 ` Juanma Barranquero @ 2015-10-16 5:42 ` martin rudalics 2015-10-16 7:10 ` Making --with-wide-int the default (was: Dynamic loading progress) Eli Zaretskii 2015-10-16 7:09 ` Making --with-wide-int the default (was: Dynamic loading progress) Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: martin rudalics @ 2015-10-16 5:42 UTC (permalink / raw) To: Juanma Barranquero, Eli Zaretskii Cc: Aurélien Aptel, p.stephani2, Daniel Colascione, Stephen Leake, Emacs developers >> Please don't assume that --with-wide-int is some rare marginal use >> case. I configure Emacs with it all the time, and intend to suggest >> that 32-bit builds at least on MS-Windows always use it. > > Why isn't it the default, then (for 32-bit builds)? Are there any downsides? Here emacs.exe grows from 60 to 70 MB when configuring --with-wide-int. martin ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default (was: Dynamic loading progress) 2015-10-16 5:42 ` martin rudalics @ 2015-10-16 7:10 ` Eli Zaretskii 2015-10-16 7:34 ` Making --with-wide-int the default martin rudalics 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-10-16 7:10 UTC (permalink / raw) To: martin rudalics; +Cc: lekktu, emacs-devel > Date: Fri, 16 Oct 2015 07:42:00 +0200 > From: martin rudalics <rudalics@gmx.at> > CC: Aurélien Aptel <aurelien.aptel+emacs@gmail.com>, > p.stephani2@gmail.com, Daniel Colascione <dancol@dancol.org>, > Stephen Leake <stephen_leake@stephe-leake.org>, > Emacs developers <emacs-devel@gnu.org> > > >> Please don't assume that --with-wide-int is some rare marginal use > >> case. I configure Emacs with it all the time, and intend to suggest > >> that 32-bit builds at least on MS-Windows always use it. > > > > Why isn't it the default, then (for 32-bit builds)? Are there any downsides? > > Here emacs.exe grows from 60 to 70 MB when configuring --with-wide-int. You should compare stripped binaries, not unstripped ones. 85% of those 70MB is DWARF debug info. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 7:10 ` Making --with-wide-int the default (was: Dynamic loading progress) Eli Zaretskii @ 2015-10-16 7:34 ` martin rudalics 2015-10-16 8:10 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: martin rudalics @ 2015-10-16 7:34 UTC (permalink / raw) To: Eli Zaretskii; +Cc: lekktu, emacs-devel >> Here emacs.exe grows from 60 to 70 MB when configuring --with-wide-int. > > You should compare stripped binaries, not unstripped ones. A 15% increase for unstripped binaries strikes me as remarkable though. > 85% of > those 70MB is DWARF debug info. Obviously. Does that info grow by 8.5 MB when configuring --with-wide-int? martin ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 7:34 ` Making --with-wide-int the default martin rudalics @ 2015-10-16 8:10 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-10-16 8:10 UTC (permalink / raw) To: martin rudalics; +Cc: lekktu, emacs-devel > Date: Fri, 16 Oct 2015 09:34:24 +0200 > From: martin rudalics <rudalics@gmx.at> > CC: lekktu@gmail.com, emacs-devel@gnu.org > > >> Here emacs.exe grows from 60 to 70 MB when configuring --with-wide-int. > > > > You should compare stripped binaries, not unstripped ones. > > A 15% increase for unstripped binaries strikes me as remarkable though. 15% of 10MB is much less than 15% of 60MB. > > 85% of > > those 70MB is DWARF debug info. > > Obviously. Does that info grow by 8.5 MB when configuring > --with-wide-int? I don't know. I never bothered to find out. I generally consider the size of the binary on disk uninteresting. The size of the Emacs memory footprint after startup is 17MB vs 15MB for the non-wide-int build. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default (was: Dynamic loading progress) 2015-10-16 0:55 ` Juanma Barranquero 2015-10-16 5:42 ` martin rudalics @ 2015-10-16 7:09 ` Eli Zaretskii 2015-10-16 7:26 ` Juanma Barranquero 2015-10-16 8:03 ` Making --with-wide-int the default Paul Eggert 1 sibling, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-10-16 7:09 UTC (permalink / raw) To: Juanma Barranquero, Paul Eggert; +Cc: emacs-devel > From: Juanma Barranquero <lekktu@gmail.com> > Date: Fri, 16 Oct 2015 02:55:47 +0200 > Cc: Aurélien Aptel <aurelien.aptel+emacs@gmail.com>, > p.stephani2@gmail.com, Daniel Colascione <dancol@dancol.org>, > Stephen Leake <stephen_leake@stephe-leake.org>, Emacs developers <emacs-devel@gnu.org> > > On Thu, Oct 15, 2015 at 5:41 PM, Eli Zaretskii <eliz@gnu.org> wrote: > > > Please don't assume that --with-wide-int is some rare marginal use > > case. I configure Emacs with it all the time, and intend to suggest > > that 32-bit builds at least on MS-Windows always use it. > > Why isn't it the default, then (for 32-bit builds)? Are there any downsides? If there is a downside, I haven't found it yet (on MS-Windows). There's some slowdown, but it all but disappears in an optimized build. And being able to have a 2GB buffer instead of 512MB maximum is IMO worth that. 61-bit integer arithmetics is also nothing to disregard easily. To make it the default for all 32-bit builds, we should make sure it works well on the other supported platforms. Perhaps Paul could tell which platforms he found this to work on, and then we could decide. In any case, the time to make the decision is NOW, because this will need time for us to be sure any serious bugs are fixed before Emacs 25.1 is released. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default (was: Dynamic loading progress) 2015-10-16 7:09 ` Making --with-wide-int the default (was: Dynamic loading progress) Eli Zaretskii @ 2015-10-16 7:26 ` Juanma Barranquero 2015-10-16 8:17 ` Eli Zaretskii 2015-10-16 8:03 ` Making --with-wide-int the default Paul Eggert 1 sibling, 1 reply; 765+ messages in thread From: Juanma Barranquero @ 2015-10-16 7:26 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Paul Eggert, Emacs developers [-- Attachment #1: Type: text/plain, Size: 645 bytes --] On Fri, Oct 16, 2015 at 9:09 AM, Eli Zaretskii <eliz@gnu.org> wrote: > There's some slowdown, but it all but disappears in an optimized > build. Hmm, I just built with --with-wide-int, and I don't notice the slowdown, perhaps because I also build with -O0 and --enable-checking=yes,glyphs, so it's already a bit slow. > In any case, the time to make the decision is NOW, because this will > need time for us to be sure any serious bugs are fixed before Emacs > 25.1 is released. Then perhaps we should enable it in all 32-bit platforms and just wait for the fallout. We can always fall back to the current default if things don't look good. [-- Attachment #2: Type: text/html, Size: 851 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default (was: Dynamic loading progress) 2015-10-16 7:26 ` Juanma Barranquero @ 2015-10-16 8:17 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-10-16 8:17 UTC (permalink / raw) To: Juanma Barranquero; +Cc: eggert, emacs-devel > From: Juanma Barranquero <lekktu@gmail.com> > Date: Fri, 16 Oct 2015 09:26:23 +0200 > Cc: Paul Eggert <eggert@cs.ucla.edu>, Emacs developers <emacs-devel@gnu.org> > > > There's some slowdown, but it all but disappears in an optimized > > build. > > Hmm, I just built with --with-wide-int, and I don't notice the slowdown, > perhaps because I also build with -O0 and --enable-checking=yes,glyphs, so it's > already a bit slow. You need to run measurable benchmarks, in order to see it. > Then perhaps we should enable it in all 32-bit platforms and just wait for the > fallout. We can always fall back to the current default if things don't look > good. That'd be my tendency, yes. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 7:09 ` Making --with-wide-int the default (was: Dynamic loading progress) Eli Zaretskii 2015-10-16 7:26 ` Juanma Barranquero @ 2015-10-16 8:03 ` Paul Eggert 2015-10-16 8:15 ` Eli Zaretskii 2015-10-16 8:18 ` David Kastrup 1 sibling, 2 replies; 765+ messages in thread From: Paul Eggert @ 2015-10-16 8:03 UTC (permalink / raw) To: Eli Zaretskii, Juanma Barranquero; +Cc: emacs-devel Eli Zaretskii wrote: > To make it the default for all 32-bit builds, we should make sure it > works well on the other supported platforms. Perhaps Paul could tell > which platforms he found this to work on, and then we could decide. --with-wide-int is not the default because Stefan was worried about its performance implications on older, slower 32-bit machines (such as Stefan's and/or RMS's laptops at the time, if I recall correctly). There shouldn't be any correctness problem with it; it's a performance issue. I typically use 64-bit platforms nowadays, where the issue is moot. When I do use 32-bit platforms, I normally configure --with-wide-int. There is roughly a 30% CPU hit and maybe a 60% hit on virtual memory, but it's worth it to me (I normally don't notice the difference). ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 8:03 ` Making --with-wide-int the default Paul Eggert @ 2015-10-16 8:15 ` Eli Zaretskii 2015-10-16 8:27 ` Paul Eggert 2015-10-16 8:28 ` Juanma Barranquero 2015-10-16 8:18 ` David Kastrup 1 sibling, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-10-16 8:15 UTC (permalink / raw) To: Paul Eggert; +Cc: lekktu, emacs-devel > Cc: emacs-devel@gnu.org > From: Paul Eggert <eggert@cs.ucla.edu> > Date: Fri, 16 Oct 2015 01:03:15 -0700 > > Eli Zaretskii wrote: > > To make it the default for all 32-bit builds, we should make sure it > > works well on the other supported platforms. Perhaps Paul could tell > > which platforms he found this to work on, and then we could decide. > > --with-wide-int is not the default because Stefan was worried about its > performance implications on older, slower 32-bit machines (such as Stefan's > and/or RMS's laptops at the time, if I recall correctly). There shouldn't be any > correctness problem with it; it's a performance issue. > > I typically use 64-bit platforms nowadays, where the issue is moot. When I do > use 32-bit platforms, I normally configure --with-wide-int. There is roughly a > 30% CPU hit and maybe a 60% hit on virtual memory, but it's worth it to me (I > normally don't notice the difference). Thanks, that about summarizes what I see here as well. Would you say it's safe to make this the default for Emacs 25? (If Richard reports annoying slowdown, we could suggest him to disable that at configure time. Or maybe there should be a configure-time test for CPU speed?) ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 8:15 ` Eli Zaretskii @ 2015-10-16 8:27 ` Paul Eggert 2015-10-16 8:31 ` David Kastrup 2015-11-11 18:43 ` Eli Zaretskii 2015-10-16 8:28 ` Juanma Barranquero 1 sibling, 2 replies; 765+ messages in thread From: Paul Eggert @ 2015-10-16 8:27 UTC (permalink / raw) To: Eli Zaretskii; +Cc: lekktu, emacs-devel Eli Zaretskii wrote: > Would you say it's safe to make this the default for Emacs 25? I'd say it's safe, yes. --with-wide-int assumes 64-bit int but since we're requiring C99-or-later now this should be safe. And as you say, if there are performance problems people can configure --with-wide-int=no. I guess the main problem will be people configuring with --enable-checking and with CFLAGS=-g0 on old slow 32-bit machines. However, people using non-default flags can just add --with-wide-int=no to their mix of flags, so this should be OK. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 8:27 ` Paul Eggert @ 2015-10-16 8:31 ` David Kastrup 2015-10-16 9:12 ` Eli Zaretskii 2015-10-16 15:29 ` Paul Eggert 2015-11-11 18:43 ` Eli Zaretskii 1 sibling, 2 replies; 765+ messages in thread From: David Kastrup @ 2015-10-16 8:31 UTC (permalink / raw) To: Paul Eggert; +Cc: lekktu, Eli Zaretskii, emacs-devel Paul Eggert <eggert@cs.ucla.edu> writes: > Eli Zaretskii wrote: >> Would you say it's safe to make this the default for Emacs 25? > > I'd say it's safe, yes. --with-wide-int assumes 64-bit int but since > we're requiring C99-or-later now this should be safe. And as you say, > if there are performance problems people can configure > --with-wide-int=no. I don't it's sensible to configure a non-native default turning everything into multiple-register operations and obliterating compact data structures matching the architecture's choices. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 8:31 ` David Kastrup @ 2015-10-16 9:12 ` Eli Zaretskii 2015-10-16 9:24 ` David Kastrup 2015-10-16 9:26 ` David Kastrup 2015-10-16 15:29 ` Paul Eggert 1 sibling, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-10-16 9:12 UTC (permalink / raw) To: David Kastrup; +Cc: lekktu, eggert, emacs-devel > From: David Kastrup <dak@gnu.org> > Cc: Eli Zaretskii <eliz@gnu.org>, lekktu@gmail.com, emacs-devel@gnu.org > Date: Fri, 16 Oct 2015 10:31:32 +0200 > > I don't it's sensible to configure a non-native default turning > everything into multiple-register operations and obliterating compact > data structures matching the architecture's choices. We only use 64-bit types in EMACS_INT, i.e. variables that reference buffer and string positions. All the rest is kept intact. What is "non-native" about 'long long int'? Do you really use 32-bit GNU/Linux machines? I cannot even easily find such beasts. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 9:12 ` Eli Zaretskii @ 2015-10-16 9:24 ` David Kastrup 2015-10-16 9:26 ` David Kastrup 1 sibling, 0 replies; 765+ messages in thread From: David Kastrup @ 2015-10-16 9:24 UTC (permalink / raw) To: Eli Zaretskii; +Cc: lekktu, eggert, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: David Kastrup <dak@gnu.org> >> Cc: Eli Zaretskii <eliz@gnu.org>, lekktu@gmail.com, emacs-devel@gnu.org >> Date: Fri, 16 Oct 2015 10:31:32 +0200 >> >> I don't it's sensible to configure a non-native default turning >> everything into multiple-register operations and obliterating compact >> data structures matching the architecture's choices. > > We only use 64-bit types in EMACS_INT, i.e. variables that reference > buffer and string positions. All the rest is kept intact. > > What is "non-native" about 'long long int'? > > Do you really use 32-bit GNU/Linux machines? I cannot even easily > find such beasts. Uh, that's not hard. I don't say that my CPU is incapable of going 64bit. But the system is 32bit mainly for disk space reasons (SSD). For a while, I even had a 64bit kernel running with a 32bit userland (which allowed me to create 64-bit executables and test them as well as the default 32-bit executables), but since this computer was given to me as a replacement for a computer where the hardware gave up, I am stuck to now having an NVidia card and the stupid binary-blob driver fails to figure out how to compile in a 64-bit kernel when the userland is 32-bit. So I am currently back again to a 32-bit kernel as well as to a 32-bit system. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 9:12 ` Eli Zaretskii 2015-10-16 9:24 ` David Kastrup @ 2015-10-16 9:26 ` David Kastrup 2015-10-16 10:12 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: David Kastrup @ 2015-10-16 9:26 UTC (permalink / raw) To: Eli Zaretskii; +Cc: lekktu, eggert, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: David Kastrup <dak@gnu.org> >> Cc: Eli Zaretskii <eliz@gnu.org>, lekktu@gmail.com, emacs-devel@gnu.org >> Date: Fri, 16 Oct 2015 10:31:32 +0200 >> >> I don't it's sensible to configure a non-native default turning >> everything into multiple-register operations and obliterating compact >> data structures matching the architecture's choices. > > We only use 64-bit types in EMACS_INT, i.e. variables that reference > buffer and string positions. All the rest is kept intact. > > What is "non-native" about 'long long int'? Register lengths and opcodes. You need two registers for every operation, and several opcodes. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 9:26 ` David Kastrup @ 2015-10-16 10:12 ` Eli Zaretskii 2015-10-16 10:28 ` David Kastrup 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-10-16 10:12 UTC (permalink / raw) To: David Kastrup; +Cc: lekktu, eggert, emacs-devel > From: David Kastrup <dak@gnu.org> > Cc: lekktu@gmail.com, eggert@cs.ucla.edu, emacs-devel@gnu.org > Date: Fri, 16 Oct 2015 11:26:27 +0200 > > > What is "non-native" about 'long long int'? > > Register lengths and opcodes. You need two registers for every > operation, and several opcodes. Yes, and the compiler already implements that in the most efficient way possible. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 10:12 ` Eli Zaretskii @ 2015-10-16 10:28 ` David Kastrup 2015-10-16 13:22 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: David Kastrup @ 2015-10-16 10:28 UTC (permalink / raw) To: Eli Zaretskii; +Cc: lekktu, eggert, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: David Kastrup <dak@gnu.org> >> Cc: lekktu@gmail.com, eggert@cs.ucla.edu, emacs-devel@gnu.org >> Date: Fri, 16 Oct 2015 11:26:27 +0200 >> >> > What is "non-native" about 'long long int'? >> >> Register lengths and opcodes. You need two registers for every >> operation, and several opcodes. > > Yes, and the compiler already implements that in the most efficient > way possible. And GMP makes use of that. "The most efficient way possible" is still less efficient than using 32bit. Particularly regarding storage efficiency. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 10:28 ` David Kastrup @ 2015-10-16 13:22 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-10-16 13:22 UTC (permalink / raw) To: David Kastrup; +Cc: lekktu, eggert, emacs-devel > From: David Kastrup <dak@gnu.org> > Cc: lekktu@gmail.com, eggert@cs.ucla.edu, emacs-devel@gnu.org > Date: Fri, 16 Oct 2015 12:28:10 +0200 > > >> > What is "non-native" about 'long long int'? > >> > >> Register lengths and opcodes. You need two registers for every > >> operation, and several opcodes. > > > > Yes, and the compiler already implements that in the most efficient > > way possible. > > And GMP makes use of that. But at the cost of a function call, which brings its own overhead. > "The most efficient way possible" is still less efficient than using > 32bit. You cannot implement 32-bit buffer positions using a 32-bit C data type. You need a few more bits. But you know this, so I have a feeling we are talking past each other. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 8:31 ` David Kastrup 2015-10-16 9:12 ` Eli Zaretskii @ 2015-10-16 15:29 ` Paul Eggert 1 sibling, 0 replies; 765+ messages in thread From: Paul Eggert @ 2015-10-16 15:29 UTC (permalink / raw) To: David Kastrup; +Cc: lekktu, Eli Zaretskii, emacs-devel David Kastrup wrote: > I don't it's sensible to configure a non-native default turning > everything into multiple-register operations and obliterating compact > data structures matching the architecture's choices. That's what I was worried about too, before I implemented --with-wide-int. But it turned out to not be a problem. Performance is a bit worse, but I have to measure it to see it. This can be surprising, until you try it. For example, on 32-bit x86, the hot path (cdr of a cons) for the Fcdr function is 9 instructions with a narrow int, and 11 instructions --with-wide-int. Most of those 9 instructions are call overhead and bit-twiddling for runtime tests, and these are the same either way. --with-wide-int causes Fcdr to need one extra instruction to load the extra word of the argument, and one extra instruction to load the extra word of the result, and that's it. If you're interested in squeezing out more performance on a --with-wide-int configuration, you can try the x32 ABI. E.g., see <https://wiki.debian.org/X32Port> for Debian or Ubuntu. I haven't bothered, though, as x86 is good enough and works everywhere. Of course I'd rather have something with GMP and bignums. But that's considerably more work than --with-wide-int. > a GMP number should be > converted back to a native LISP integer whenever it's small enough > again. Obviously. And one can even work around the = vs eq problem for larger integers. But these are things that are still on the drawing board. --with-wide-int works now. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 8:27 ` Paul Eggert 2015-10-16 8:31 ` David Kastrup @ 2015-11-11 18:43 ` Eli Zaretskii 2015-11-12 8:23 ` martin rudalics 2015-11-12 16:29 ` Juanma Barranquero 1 sibling, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-11 18:43 UTC (permalink / raw) To: John Wiegley; +Cc: emacs-devel > Cc: lekktu@gmail.com, emacs-devel@gnu.org > From: Paul Eggert <eggert@cs.ucla.edu> > Date: Fri, 16 Oct 2015 01:27:38 -0700 > > Eli Zaretskii wrote: > > Would you say it's safe to make this the default for Emacs 25? > > I'd say it's safe, yes. --with-wide-int assumes 64-bit int but since we're > requiring C99-or-later now this should be safe. And as you say, if there are > performance problems people can configure --with-wide-int=no. > > I guess the main problem will be people configuring with --enable-checking and > with CFLAGS=-g0 on old slow 32-bit machines. However, people using non-default > flags can just add --with-wide-int=no to their mix of flags, so this should be OK. Based on this, I'd like to turn --with-wide-int on by default. Any last-minute objections? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-11 18:43 ` Eli Zaretskii @ 2015-11-12 8:23 ` martin rudalics 2015-11-12 16:19 ` Eli Zaretskii 2015-11-12 22:31 ` Richard Stallman 2015-11-12 16:29 ` Juanma Barranquero 1 sibling, 2 replies; 765+ messages in thread From: martin rudalics @ 2015-11-12 8:23 UTC (permalink / raw) To: Eli Zaretskii, John Wiegley; +Cc: emacs-devel > Based on this, I'd like to turn --with-wide-int on by default. Any > last-minute objections? With a very visible description of how to turn it off, please. Mine is apparently still one of these "old slow 32-bit machines" :-( martin ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-12 8:23 ` martin rudalics @ 2015-11-12 16:19 ` Eli Zaretskii 2015-11-12 18:00 ` martin rudalics 2015-11-12 22:31 ` Richard Stallman 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-12 16:19 UTC (permalink / raw) To: martin rudalics; +Cc: jwiegley, emacs-devel > Date: Thu, 12 Nov 2015 09:23:02 +0100 > From: martin rudalics <rudalics@gmx.at> > CC: emacs-devel@gnu.org > > > Based on this, I'd like to turn --with-wide-int on by default. Any > > last-minute objections? > > With a very visible description of how to turn it off, please. I intended to document --without-wide-int in NEWS. Is that visible enough? > Mine is apparently still one of these "old slow 32-bit machines" :-( What kind of CPU do you have there? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-12 16:19 ` Eli Zaretskii @ 2015-11-12 18:00 ` martin rudalics 0 siblings, 0 replies; 765+ messages in thread From: martin rudalics @ 2015-11-12 18:00 UTC (permalink / raw) To: Eli Zaretskii; +Cc: jwiegley, emacs-devel > I intended to document --without-wide-int in NEWS. Is that visible > enough? Let's hope so. >> Mine is apparently still one of these "old slow 32-bit machines" :-( > > What kind of CPU do you have there? 1.8 GHz Dual Pentium. martin ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-12 8:23 ` martin rudalics 2015-11-12 16:19 ` Eli Zaretskii @ 2015-11-12 22:31 ` Richard Stallman 2015-11-13 7:43 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Richard Stallman @ 2015-11-12 22:31 UTC (permalink / raw) To: martin rudalics; +Cc: jwiegley, eliz, emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > > Based on this, I'd like to turn --with-wide-int on by default. Any > > last-minute objections? > With a very visible description of how to turn it off, please. Mine is > apparently still one of these "old slow 32-bit machines" :-( People who build Emacs should not _have_ to know anything about --with-wide-int. We should make configure automatically do the right thing on machines that don't support wide ints. -- Dr Richard Stallman President, Free Software Foundation (gnu.org, fsf.org) Internet Hall-of-Famer (internethalloffame.org) Skype: No way! See stallman.org/skype.html. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-12 22:31 ` Richard Stallman @ 2015-11-13 7:43 ` Eli Zaretskii 2015-11-13 7:52 ` Paul Eggert ` (2 more replies) 0 siblings, 3 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-13 7:43 UTC (permalink / raw) To: rms; +Cc: rudalics, emacs-devel, jwiegley > From: Richard Stallman <rms@gnu.org> > CC: eliz@gnu.org, jwiegley@gmail.com, emacs-devel@gnu.org > Date: Thu, 12 Nov 2015 17:31:51 -0500 > > > > Based on this, I'd like to turn --with-wide-int on by default. Any > > > last-minute objections? > > > With a very visible description of how to turn it off, please. Mine is > > apparently still one of these "old slow 32-bit machines" :-( > > People who build Emacs should not _have_ to know anything about > --with-wide-int. We should make configure automatically do the right > thing on machines that don't support wide ints. There are no machines we know of that cannot support wide ints. The only problem is that using wide ints produces a somewhat slower Emacs (Paul reported a 30% slowdown), so on slow machines this could be annoying. However, the annoyance is in the eyes of the beholder, and the decision whether the slowdown is worth the 4-fold increase in the size of the largest buffer you can have (respectively, the largest file you can edit) is something only humans can make. E.g., many people here routinely run Emacs configured with run-time checks and compiled without optimizations, which makes it 2 - 3 times slower than the optimized version. So evidently a somewhat slower Emacs is mostly bearable, at least to people on this list. The Emacs build procedure provides about 40 --with-SOMETHING switch, see "./configure --help". The above-mentioned one is just one of them. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-13 7:43 ` Eli Zaretskii @ 2015-11-13 7:52 ` Paul Eggert 2015-11-13 8:05 ` martin rudalics 2015-11-13 9:11 ` David Kastrup 2 siblings, 0 replies; 765+ messages in thread From: Paul Eggert @ 2015-11-13 7:52 UTC (permalink / raw) To: Eli Zaretskii, rms; +Cc: rudalics, jwiegley, emacs-devel Eli Zaretskii wrote: > There are no machines we know of that cannot support wide ints. Yes, Emacs has assumed C99-or-better since May 2014 (see Bug#17487), and every such platform supports long long, used to implement wide ints on 32-bit hosts. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-13 7:43 ` Eli Zaretskii 2015-11-13 7:52 ` Paul Eggert @ 2015-11-13 8:05 ` martin rudalics 2015-11-13 8:24 ` Eli Zaretskii 2015-11-13 9:11 ` David Kastrup 2 siblings, 1 reply; 765+ messages in thread From: martin rudalics @ 2015-11-13 8:05 UTC (permalink / raw) To: Eli Zaretskii, rms; +Cc: jwiegley, emacs-devel > E.g., many people here > routinely run Emacs configured with run-time checks and compiled > without optimizations, which makes it 2 - 3 times slower than the > optimized version. Unfortunately I can't do that any more since last year. With run-time checks and without optimization Emacs has become so slow that it was virtually impossible to use it for editing. Display of text I typed lagged behind by up to three or four characters. martin ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-13 8:05 ` martin rudalics @ 2015-11-13 8:24 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-13 8:24 UTC (permalink / raw) To: martin rudalics; +Cc: jwiegley, rms, emacs-devel > Date: Fri, 13 Nov 2015 09:05:25 +0100 > From: martin rudalics <rudalics@gmx.at> > CC: emacs-devel@gnu.org, jwiegley@gmail.com > > > E.g., many people here > > routinely run Emacs configured with run-time checks and compiled > > without optimizations, which makes it 2 - 3 times slower than the > > optimized version. > > Unfortunately I can't do that any more since last year. With run-time > checks and without optimization Emacs has become so slow that it was > virtually impossible to use it for editing. Display of text I typed > lagged behind by up to three or four characters. My point is that the configure script cannot reasonably be expected to find out that this is what will happen on a particular machine. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-13 7:43 ` Eli Zaretskii 2015-11-13 7:52 ` Paul Eggert 2015-11-13 8:05 ` martin rudalics @ 2015-11-13 9:11 ` David Kastrup 2015-11-13 9:30 ` Eli Zaretskii 2015-11-13 22:03 ` Richard Stallman 2 siblings, 2 replies; 765+ messages in thread From: David Kastrup @ 2015-11-13 9:11 UTC (permalink / raw) To: Eli Zaretskii; +Cc: rudalics, jwiegley, rms, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Richard Stallman <rms@gnu.org> >> CC: eliz@gnu.org, jwiegley@gmail.com, emacs-devel@gnu.org >> Date: Thu, 12 Nov 2015 17:31:51 -0500 >> >> > > Based on this, I'd like to turn --with-wide-int on by default. Any >> > > last-minute objections? >> >> > With a very visible description of how to turn it off, please. Mine is >> > apparently still one of these "old slow 32-bit machines" :-( >> >> People who build Emacs should not _have_ to know anything about >> --with-wide-int. We should make configure automatically do the right >> thing on machines that don't support wide ints. > > There are no machines we know of that cannot support wide ints. The > only problem is that using wide ints produces a somewhat slower Emacs > (Paul reported a 30% slowdown), so on slow machines this could be > annoying. Also the cell size doubles, so the Lisp data structures take more memory. I think it is quite reasonable _not_ to use wide ints by default on architectures with a 32-bit address space. Everything takes up more memory, the maximum of virtual address space is something like 3GB anyway so it's not like you could hope to increase the amount of stuff you could be editing all that much: it is more likely that with several buffers loaded at once, you'll _decrease_ the overall amount of stuff you can keep loaded into buffers at the same time. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-13 9:11 ` David Kastrup @ 2015-11-13 9:30 ` Eli Zaretskii 2015-11-13 11:52 ` David Kastrup 2015-11-13 22:03 ` Richard Stallman 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-13 9:30 UTC (permalink / raw) To: David Kastrup; +Cc: rudalics, jwiegley, rms, emacs-devel > From: David Kastrup <dak@gnu.org> > Cc: rms@gnu.org, rudalics@gmx.at, emacs-devel@gnu.org, jwiegley@gmail.com > Date: Fri, 13 Nov 2015 10:11:49 +0100 > > Also the cell size doubles, so the Lisp data structures take more > memory. I think it is quite reasonable _not_ to use wide ints by > default on architectures with a 32-bit address space. Everything takes > up more memory, the maximum of virtual address space is something like > 3GB anyway so it's not like you could hope to increase the amount of > stuff you could be editing all that much: it is more likely that with > several buffers loaded at once, you'll _decrease_ the overall amount of > stuff you can keep loaded into buffers at the same time. I think the much large buffer size limit is more important than these considerations. (Your fears about decreasing the buffer size are unfounded: I actually tried using 1.5GB buffers, and it worked every time). And there's a configure-time switch to not use wide ints for those who think otherwise. So on balance, I think it's an improvement. If I'm wrong, we have the pretest to indicate that, and we can always turn it back off by default if needed before the release. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-13 9:30 ` Eli Zaretskii @ 2015-11-13 11:52 ` David Kastrup 2015-11-13 18:56 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: David Kastrup @ 2015-11-13 11:52 UTC (permalink / raw) To: Eli Zaretskii; +Cc: rudalics, emacs-devel, rms, jwiegley Eli Zaretskii <eliz@gnu.org> writes: >> From: David Kastrup <dak@gnu.org> >> Cc: rms@gnu.org, rudalics@gmx.at, emacs-devel@gnu.org, jwiegley@gmail.com >> Date: Fri, 13 Nov 2015 10:11:49 +0100 >> >> Also the cell size doubles, so the Lisp data structures take more >> memory. I think it is quite reasonable _not_ to use wide ints by >> default on architectures with a 32-bit address space. Everything takes >> up more memory, the maximum of virtual address space is something like >> 3GB anyway so it's not like you could hope to increase the amount of >> stuff you could be editing all that much: it is more likely that with >> several buffers loaded at once, you'll _decrease_ the overall amount of >> stuff you can keep loaded into buffers at the same time. > > I think the much large buffer size limit is more important than these > considerations. (Your fears about decreasing the buffer size are > unfounded: I actually tried using 1.5GB buffers, and it worked every > time). "with several buffers loaded at once". If buffer size was so much of a concern, we could represent integers like XEmacs does (basically with a single tag bit), allowing for buffers of 1GB size. When the maximal virtual memory size is something like 3GB, I don't think we'd be missing out on much. People wanting to edit files of several gigabyte size regularly will not be using a 32-bit userland these days anyway. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-13 11:52 ` David Kastrup @ 2015-11-13 18:56 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-13 18:56 UTC (permalink / raw) To: David Kastrup; +Cc: rudalics, emacs-devel, rms, jwiegley > From: David Kastrup <dak@gnu.org> > Cc: rudalics@gmx.at, jwiegley@gmail.com, rms@gnu.org, emacs-devel@gnu.org > Date: Fri, 13 Nov 2015 12:52:30 +0100 > > > I think the much large buffer size limit is more important than these > > considerations. (Your fears about decreasing the buffer size are > > unfounded: I actually tried using 1.5GB buffers, and it worked every > > time). > > "with several buffers loaded at once". Yes, with several buffers. > If buffer size was so much of a concern, we could represent integers > like XEmacs does (basically with a single tag bit), allowing for > buffers of 1GB size. We could, but we didn't. Instead, we have --with-wide-ints. > People wanting to edit files of several gigabyte size regularly will > not be using a 32-bit userland these days anyway. If you need to do that on a 32-bit system, you have no other choice. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-13 9:11 ` David Kastrup 2015-11-13 9:30 ` Eli Zaretskii @ 2015-11-13 22:03 ` Richard Stallman 2015-11-14 8:43 ` Eli Zaretskii 2015-11-20 2:20 ` Stefan Monnier 1 sibling, 2 replies; 765+ messages in thread From: Richard Stallman @ 2015-11-13 22:03 UTC (permalink / raw) To: David Kastrup; +Cc: rudalics, eliz, emacs-devel, jwiegley [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > I think it is quite reasonable _not_ to use wide ints by > default on architectures with a 32-bit address space. +1. -- Dr Richard Stallman President, Free Software Foundation (gnu.org, fsf.org) Internet Hall-of-Famer (internethalloffame.org) Skype: No way! See stallman.org/skype.html. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-13 22:03 ` Richard Stallman @ 2015-11-14 8:43 ` Eli Zaretskii 2015-11-14 8:54 ` martin rudalics ` (3 more replies) 2015-11-20 2:20 ` Stefan Monnier 1 sibling, 4 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-14 8:43 UTC (permalink / raw) To: rms; +Cc: rudalics, dak, emacs-devel, jwiegley > From: Richard Stallman <rms@gnu.org> > CC: eliz@gnu.org, rudalics@gmx.at, jwiegley@gmail.com, > emacs-devel@gnu.org > Date: Fri, 13 Nov 2015 17:03:10 -0500 > > > I think it is quite reasonable _not_ to use wide ints by > > default on architectures with a 32-bit address space. > > +1. Faced with such powerful opposition, I guess this now becomes your decision, John. I can always build my own Emacs with that option; the question is what we want for the majority of our users on 32-bit systems. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-14 8:43 ` Eli Zaretskii @ 2015-11-14 8:54 ` martin rudalics 2015-11-14 17:38 ` Ulrich Mueller ` (2 subsequent siblings) 3 siblings, 0 replies; 765+ messages in thread From: martin rudalics @ 2015-11-14 8:54 UTC (permalink / raw) To: Eli Zaretskii, rms; +Cc: jwiegley, dak, emacs-devel > Faced with such powerful opposition, I guess this now becomes your > decision, John. I can always build my own Emacs with that option; the > question is what we want for the majority of our users on 32-bit > systems. Please note that I'm not part of that opposition. I just wanted to mention that my current configuration leaves me no other choice than to build without that option. And if it were the first time I ran into the problem that my build is unbearably slow, I'd like to have some guidance on how to possibly get out of it. martin ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-14 8:43 ` Eli Zaretskii 2015-11-14 8:54 ` martin rudalics @ 2015-11-14 17:38 ` Ulrich Mueller 2015-11-15 20:14 ` Eli Zaretskii 2015-11-15 7:05 ` Paul Eggert 2015-11-15 16:01 ` David Kastrup 3 siblings, 1 reply; 765+ messages in thread From: Ulrich Mueller @ 2015-11-14 17:38 UTC (permalink / raw) To: Eli Zaretskii; +Cc: rudalics, jwiegley, dak, rms, emacs-devel >>>>> On Sat, 14 Nov 2015, Eli Zaretskii wrote: > Faced with such powerful opposition, I guess this now becomes your > decision, John. I can always build my own Emacs with that option; the > question is what we want for the majority of our users on 32-bit > systems. In case you want any feedback from distros, Gentoo makes the option available to users as the "wide-int" use flag, and the default is off. I've not seen a single complaint from users that we should change that default. (So most likely the Gentoo default will stay off, regardless of what you decide to do with the upstream default.) Ulrich ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-14 17:38 ` Ulrich Mueller @ 2015-11-15 20:14 ` Eli Zaretskii 2015-11-15 20:50 ` David Kastrup 2015-11-15 21:04 ` Ulrich Mueller 0 siblings, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-15 20:14 UTC (permalink / raw) To: Ulrich Mueller; +Cc: rudalics, dak, emacs-devel, rms, jwiegley > Date: Sat, 14 Nov 2015 18:38:37 +0100 > From: Ulrich Mueller <ulm@gentoo.org> > Cc: rudalics@gmx.at, jwiegley@gmail.com, dak@gnu.org, rms@gnu.org, > emacs-devel@gnu.org > > In case you want any feedback from distros, Gentoo makes the option > available to users as the "wide-int" use flag, and the default is off. > I've not seen a single complaint from users that we should change that > default. (So most likely the Gentoo default will stay off, regardless > of what you decide to do with the upstream default.) Did the option you offer mention the fact that using it enlarges the maximum buffer and string size to (almost) 2GB? If not, it's quite possible that your users simply did not realize what this option would give them in user-level functionality, and treated it as yet another obscure build feature. Also, I must say it sounds strange to me that you wait for user complaints before you decide that some option should be on by default. Do you act the same with all the optional Emacs features, like GnuTLS or libxml2 or file notifications (or even image support)? Surely, you and your team have enough insight on the importance of each feature to make your own decisions? But I know nothing about maintaining distributions, so perhaps I'm missing something here. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-15 20:14 ` Eli Zaretskii @ 2015-11-15 20:50 ` David Kastrup 2015-11-15 21:06 ` Eli Zaretskii 2015-11-15 21:04 ` Ulrich Mueller 1 sibling, 1 reply; 765+ messages in thread From: David Kastrup @ 2015-11-15 20:50 UTC (permalink / raw) To: Eli Zaretskii; +Cc: rudalics, Ulrich Mueller, emacs-devel, rms, jwiegley Eli Zaretskii <eliz@gnu.org> writes: >> Date: Sat, 14 Nov 2015 18:38:37 +0100 >> From: Ulrich Mueller <ulm@gentoo.org> >> Cc: rudalics@gmx.at, jwiegley@gmail.com, dak@gnu.org, rms@gnu.org, >> emacs-devel@gnu.org >> >> In case you want any feedback from distros, Gentoo makes the option >> available to users as the "wide-int" use flag, and the default is off. >> I've not seen a single complaint from users that we should change that >> default. (So most likely the Gentoo default will stay off, regardless >> of what you decide to do with the upstream default.) > > Did the option you offer mention the fact that using it enlarges the > maximum buffer and string size to (almost) 2GB? If not, it's quite > possible that your users simply did not realize what this option would > give them in user-level functionality, and treated it as yet another > obscure build feature. > > Also, I must say it sounds strange to me that you wait for user > complaints before you decide that some option should be on by default. A performance hit by 30% and noticeable increase of memory usage are not exactly a bargain for being able to load ridiculously large files into an editor on a 32-bit system. If people had wagonloads of memory to spare, they'd be running 64-bit systems in the first place. > Do you act the same with all the optional Emacs features, like GnuTLS > or libxml2 or file notifications (or even image support)? Surely, you > and your team have enough insight on the importance of each feature to > make your own decisions? But I know nothing about maintaining > distributions, so perhaps I'm missing something here. Gentoo _also_ is about squeezing the most performance from your hardware by compiling with system-specific optimizations. A 30% performance hit for your text desktop affecting every editing task does not exactly fit well with that objective. I really don't get what the clamor for wide ints on a 32 bit system is supposed to be about. It's rather few people that you are doing an actual favor here. Stuff like GnuTLS or libxml2 or file notifications or image support don't bog your system down when you don't use them. Wide ints do. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-15 20:50 ` David Kastrup @ 2015-11-15 21:06 ` Eli Zaretskii 2015-11-15 22:19 ` David Kastrup 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-15 21:06 UTC (permalink / raw) To: David Kastrup; +Cc: rudalics, ulm, emacs-devel, rms, jwiegley > From: David Kastrup <dak@gnu.org> > Cc: Ulrich Mueller <ulm@gentoo.org>, rudalics@gmx.at, jwiegley@gmail.com, rms@gnu.org, emacs-devel@gnu.org > Date: Sun, 15 Nov 2015 21:50:27 +0100 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> Date: Sat, 14 Nov 2015 18:38:37 +0100 > >> From: Ulrich Mueller <ulm@gentoo.org> > >> Cc: rudalics@gmx.at, jwiegley@gmail.com, dak@gnu.org, rms@gnu.org, > >> emacs-devel@gnu.org > >> > >> In case you want any feedback from distros, Gentoo makes the option > >> available to users as the "wide-int" use flag, and the default is off. > >> I've not seen a single complaint from users that we should change that > >> default. (So most likely the Gentoo default will stay off, regardless > >> of what you decide to do with the upstream default.) > > > > Did the option you offer mention the fact that using it enlarges the > > maximum buffer and string size to (almost) 2GB? If not, it's quite > > possible that your users simply did not realize what this option would > > give them in user-level functionality, and treated it as yet another > > obscure build feature. > > > > Also, I must say it sounds strange to me that you wait for user > > complaints before you decide that some option should be on by default. > > A performance hit by 30% and noticeable increase of memory usage are not > exactly a bargain for being able to load ridiculously large files into > an editor on a 32-bit system. > > If people had wagonloads of memory to spare, they'd be running 64-bit > systems in the first place. How is this related to what I wrote, may I ask? Ulrich never mentioned these factors, and I replied to what he wrote. > I really don't get what the clamor for wide ints on a 32 bit system is > supposed to be about. It's rather few people that you are doing an > actual favor here. Stuff like GnuTLS or libxml2 or file notifications > or image support don't bog your system down when you don't use them. > Wide ints do. Once again, how is that relevant to what I wrote in my message to Ulrich? Look, it's clear that you are against this option. You made that clear several times already; repeating it time and again doesn't add weight to your opinions. Especially when those opinions are plugged with no relation whatsoever to what I wrote. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-15 21:06 ` Eli Zaretskii @ 2015-11-15 22:19 ` David Kastrup 2015-11-16 16:38 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: David Kastrup @ 2015-11-15 22:19 UTC (permalink / raw) To: Eli Zaretskii; +Cc: rudalics, ulm, emacs-devel, rms, jwiegley Eli Zaretskii <eliz@gnu.org> writes: >> From: David Kastrup <dak@gnu.org> >> Cc: Ulrich Mueller <ulm@gentoo.org>, rudalics@gmx.at, >> jwiegley@gmail.com, rms@gnu.org, emacs-devel@gnu.org >> Date: Sun, 15 Nov 2015 21:50:27 +0100 >> >> A performance hit by 30% and noticeable increase of memory usage are not >> exactly a bargain for being able to load ridiculously large files into >> an editor on a 32-bit system. >> >> If people had wagonloads of memory to spare, they'd be running 64-bit >> systems in the first place. > > How is this related to what I wrote, may I ask? Ulrich never > mentioned these factors, and I replied to what he wrote. So? You attack Ulrich because he did not sufficiently stress the advantages: >> > Did the option you offer mention the fact that using it enlarges >> > the maximum buffer and string size to (almost) 2GB? If not, it's >> > quite possible that your users simply did not realize what this >> > option would give them in user-level functionality, and treated it >> > as yet another obscure build feature. >> > >> > Also, I must say it sounds strange to me that you wait for user >> > complaints before you decide that some option should be on by >> > default. and more or less state that apparently the only reason for nobody complaining about that setting is that he has omitted to properly describe the option's advantages, not because there would be any actual justification for the chosen default. At the same time you are completely unworried about the _disadvantages_ (which affect every user editing any file, not just the ones loading files larger than 512MByte into memory) not getting mentioned at all. What's wrong with an actual qualified choice based on knowledge of both advantages and disadvantages? > Once again, how is that relevant to what I wrote in my message to > Ulrich? Because you are only interested in having the advantages of wide ints listed. > Look, it's clear that you are against this option. Not at all. I am against enabling it by default on unsuspecting users of 32bit systems. I am fine with enabling it by default on 64bit systems since on those, the gained window of usefulness between 512MB buffers and a reasonable fraction of the virtual memory available to Emacs is potentially quite larger. Also the performance cost of using 64bit entities for everything should be quite less noticeable. I am also fine with making this option an announced and properly described user option to users of a compile-your-own system like Gentoo. If you want a detailed mention of the reason for setting such an option, it does not make sense to omit the drawbacks of doing so: that seems only tailored towards having users make complaints (the absence of which you do not like) rather than an actual informed choice. The desired complaints would likely have the form "why is this option not enabled by default?" and of course there is a valid answer for that as well as a valid answer for why some user would want it enabled by default. > You made that clear several times already; repeating it time and again > doesn't add weight to your opinions. Especially when those opinions > are plugged with no relation whatsoever to what I wrote. Shrug. You don't see a relation, I see one. Others are reading this exchange, so there is a chance that it contributes to forming opinions and eventually may help with making and explaining decisions. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-15 22:19 ` David Kastrup @ 2015-11-16 16:38 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-16 16:38 UTC (permalink / raw) To: David Kastrup; +Cc: rudalics, ulm, emacs-devel, rms, jwiegley > From: David Kastrup <dak@gnu.org> > Cc: ulm@gentoo.org, rudalics@gmx.at, jwiegley@gmail.com, rms@gnu.org, emacs-devel@gnu.org > Date: Sun, 15 Nov 2015 23:19:00 +0100 > > > How is this related to what I wrote, may I ask? Ulrich never > > mentioned these factors, and I replied to what he wrote. > > So? You attack Ulrich because he did not sufficiently stress the > advantages: If Ulrich feels attacked, I apologize: I never meant anything even close. He said he had another data point related to this decision, so I thought it was fair to ask the questions that I asked about that data point. > and more or less state that apparently the only reason for nobody > complaining about that setting is that he has omitted to properly > describe the option's advantages, not because there would be any actual > justification for the chosen default. That's not what I said. What I actually said was this: > Fair enough, but then we must agree that the lack of complaints > probably says nothing at all about your users' preferences in this > matter. IOW, "the data doesn't support any conclusions". No accusations, no attack, nothing of the kind. > At the same time you are > completely unworried about the _disadvantages_ (which affect every user > editing any file, not just the ones loading files larger than 512MByte > into memory) not getting mentioned at all. IMO, the advantages far outweigh the disadvantages. In your opinion, it's the other way around. Nothing wrong here, and no reasons to imply that my opinions are somehow inferior to yours. they are just different. > What's wrong with an actual qualified choice based on knowledge of both > advantages and disadvantages? Nothing. But when you reply to what I wrote, I'd appreciate that you actually reply to the quoted parts, or else don't quote me at all. > > Once again, how is that relevant to what I wrote in my message to > > Ulrich? > > Because you are only interested in having the advantages of wide ints > listed. ??? I think now you owe me an apology. > Others are reading this exchange, so there is a chance that it > contributes to forming opinions and eventually may help with making > and explaining decisions. Indeed. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-15 20:14 ` Eli Zaretskii 2015-11-15 20:50 ` David Kastrup @ 2015-11-15 21:04 ` Ulrich Mueller 2015-11-15 21:13 ` Eli Zaretskii 2015-11-15 21:36 ` David Kastrup 1 sibling, 2 replies; 765+ messages in thread From: Ulrich Mueller @ 2015-11-15 21:04 UTC (permalink / raw) To: Eli Zaretskii; +Cc: rudalics, dak, emacs-devel, rms, jwiegley >>>>> On Sun, 15 Nov 2015, Eli Zaretskii wrote: >> Date: Sat, 14 Nov 2015 18:38:37 +0100 >> From: Ulrich Mueller <ulm@gentoo.org> >> Cc: rudalics@gmx.at, jwiegley@gmail.com, dak@gnu.org, rms@gnu.org, >> emacs-devel@gnu.org >> >> In case you want any feedback from distros, Gentoo makes the option >> available to users as the "wide-int" use flag, and the default is off. >> I've not seen a single complaint from users that we should change that >> default. (So most likely the Gentoo default will stay off, regardless >> of what you decide to do with the upstream default.) > Did the option you offer mention the fact that using it enlarges the > maximum buffer and string size to (almost) 2GB? If not, it's quite > possible that your users simply did not realize what this option would > give them in user-level functionality, and treated it as yet another > obscure build feature. This is what we have as description: app-editors/emacs:wide-int - Prefer wide Emacs integers (typically 62-bit). This option has an effect only on architectures where "long" and "long long" types have different size. Seems that we copied the first sentence from Emacs' configure --help output, which also doesn't say anything about buffer size or memory footprint. > Also, I must say it sounds strange to me that you wait for user > complaints before you decide that some option should be on by default. Well, Gentoo may be a bit special there, as we leave the choice largely to the users. There are of course defaults (set in so-called "profiles") for the most important flags. But users _will_ complain if a default is completely unreasonable. Unrelated question: Are the "62 bit" in the description above correct, or should it rather be 61 bit? Ulrich ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-15 21:04 ` Ulrich Mueller @ 2015-11-15 21:13 ` Eli Zaretskii 2015-11-15 21:36 ` David Kastrup 1 sibling, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-15 21:13 UTC (permalink / raw) To: Ulrich Mueller; +Cc: rudalics, dak, emacs-devel, rms, jwiegley > Date: Sun, 15 Nov 2015 22:04:46 +0100 > Cc: rudalics@gmx.at, jwiegley@gmail.com, dak@gnu.org, rms@gnu.org, > emacs-devel@gnu.org > From: Ulrich Mueller <ulm@gentoo.org> > > >>>>> On Sun, 15 Nov 2015, Eli Zaretskii wrote: > > >> Date: Sat, 14 Nov 2015 18:38:37 +0100 > >> From: Ulrich Mueller <ulm@gentoo.org> > >> Cc: rudalics@gmx.at, jwiegley@gmail.com, dak@gnu.org, rms@gnu.org, > >> emacs-devel@gnu.org > >> > >> In case you want any feedback from distros, Gentoo makes the option > >> available to users as the "wide-int" use flag, and the default is off. > >> I've not seen a single complaint from users that we should change that > >> default. (So most likely the Gentoo default will stay off, regardless > >> of what you decide to do with the upstream default.) > > > Did the option you offer mention the fact that using it enlarges the > > maximum buffer and string size to (almost) 2GB? If not, it's quite > > possible that your users simply did not realize what this option would > > give them in user-level functionality, and treated it as yet another > > obscure build feature. > > This is what we have as description: > > app-editors/emacs:wide-int - Prefer wide Emacs integers (typically > 62-bit). This option has an effect only on architectures where > "long" and "long long" types have different size. > > Seems that we copied the first sentence from Emacs' configure --help > output, which also doesn't say anything about buffer size or memory > footprint. Fair enough, but then we must agree that the lack of complaints probably says nothing at all about your users' preferences in this matter. > Unrelated question: Are the "62 bit" in the description above correct, > or should it rather be 61 bit? 62, including the sign bit. Try this: M-: (- most-positive-fixnum) RET and then look at the hex representation. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-15 21:04 ` Ulrich Mueller 2015-11-15 21:13 ` Eli Zaretskii @ 2015-11-15 21:36 ` David Kastrup 1 sibling, 0 replies; 765+ messages in thread From: David Kastrup @ 2015-11-15 21:36 UTC (permalink / raw) To: Ulrich Mueller; +Cc: rudalics, Eli Zaretskii, emacs-devel, rms, jwiegley Ulrich Mueller <ulm@gentoo.org> writes: >>>>>> On Sun, 15 Nov 2015, Eli Zaretskii wrote: > >>> Date: Sat, 14 Nov 2015 18:38:37 +0100 >>> From: Ulrich Mueller <ulm@gentoo.org> >>> Cc: rudalics@gmx.at, jwiegley@gmail.com, dak@gnu.org, rms@gnu.org, >>> emacs-devel@gnu.org >>> >>> In case you want any feedback from distros, Gentoo makes the option >>> available to users as the "wide-int" use flag, and the default is off. >>> I've not seen a single complaint from users that we should change that >>> default. (So most likely the Gentoo default will stay off, regardless >>> of what you decide to do with the upstream default.) > >> Did the option you offer mention the fact that using it enlarges the >> maximum buffer and string size to (almost) 2GB? If not, it's quite >> possible that your users simply did not realize what this option would >> give them in user-level functionality, and treated it as yet another >> obscure build feature. > > This is what we have as description: > > app-editors/emacs:wide-int - Prefer wide Emacs integers (typically > 62-bit). This option has an effect only on architectures where > "long" and "long long" types have different size. > > Seems that we copied the first sentence from Emacs' configure --help > output, which also doesn't say anything about buffer size or memory > footprint. It's not really "Prefer". It makes _all_ Lisp data 64 bit (allowing for 62 bit integers instead of the usual 30 bit ones), at the obvious cost of doubling the size of Lisp cells (and immediate expressions and symbols and a few other things) to a value not natively supported by instructions and registers. > Unrelated question: Are the "62 bit" in the description above correct, > or should it rather be 61 bit? Yes. The basic type tagging is 3 bits, but two tag values are reserved for integers. So effectively only 2 bits are missing from the integer range. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-14 8:43 ` Eli Zaretskii 2015-11-14 8:54 ` martin rudalics 2015-11-14 17:38 ` Ulrich Mueller @ 2015-11-15 7:05 ` Paul Eggert 2015-11-16 9:00 ` David Kastrup 2015-11-15 16:01 ` David Kastrup 3 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-15 7:05 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel Eli Zaretskii wrote: > I can always build my own Emacs with that option When I build and test 32-bit code, I typically use --with-wide-int as well. My impression is that --with-wide-int is typically better for production use these days. For older, slower platforms and with debugging turned on and/or optimization turned off, --with-wide-int may well cost more than it's worth. That being said, typical 32-bit use nowadays would probably benefit from --with-wide-int. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-15 7:05 ` Paul Eggert @ 2015-11-16 9:00 ` David Kastrup 2015-11-16 16:19 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: David Kastrup @ 2015-11-16 9:00 UTC (permalink / raw) To: Paul Eggert; +Cc: Eli Zaretskii, emacs-devel Paul Eggert <eggert@cs.ucla.edu> writes: > Eli Zaretskii wrote: >> I can always build my own Emacs with that option > > When I build and test 32-bit code, I typically use --with-wide-int as well. > > My impression is that --with-wide-int is typically better for > production use these days. For older, slower platforms and with > debugging turned on and/or optimization turned off, --with-wide-int > may well cost more than it's worth. That being said, typical 32-bit > use nowadays would probably benefit from --with-wide-int. At the risk of repeating myself: newer, faster platforms tend to run 64-bit systems anyway. Running a 32-bit system on new hardware these days implies making a _choice_ for such systems (as the hardware for memory sizes in excess of 1GB is rather consistently prepared for running 64-bit systems), for smaller code size and memory and disk impact at the cost of not being able to address humongous amounts of data in virtual memory. The rationale for such a choice is quite related to the rationale for not using wide Lisp data structures in a compilation of Emacs. A sensible system default becomes more important as Emacs gains the ability of loading modules compiled with C and accessing Elisp data structures at runtime because, as opposed to options like --without-toolkit-scroll-bars, "just compile your own binaries if you don't like the default" stops being an option when you want to make use of precompiled binary modules. It's nice that --with-wide-int is available for special needs. But on 32-bit systems, it comes at a cost that is not consistent with choosing a 32-bit system in the first place. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-16 9:00 ` David Kastrup @ 2015-11-16 16:19 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-16 16:19 UTC (permalink / raw) To: David Kastrup; +Cc: eggert, emacs-devel > From: David Kastrup <dak@gnu.org> > Cc: Eli Zaretskii <eliz@gnu.org>, emacs-devel@gnu.org > Date: Mon, 16 Nov 2015 10:00:34 +0100 > > It's nice that --with-wide-int is available for special needs. But on > 32-bit systems, it comes at a cost that is not consistent with choosing > a 32-bit system in the first place. FWIW, in my testing, the cost is mostly insignificant in any real-life session. I found Paul's estimates of 30% slowdown to be rather conservative, I can only get around 30% - 35% in a tight loop that increments a single integer variable and does nothing else. In any real-time scenario I tried, I see between 4% and 13% slowdown. And memory footprint of a large session (more than 500 buffers) is less than 5% larger with wide ints. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-14 8:43 ` Eli Zaretskii ` (2 preceding siblings ...) 2015-11-15 7:05 ` Paul Eggert @ 2015-11-15 16:01 ` David Kastrup 2015-11-15 19:36 ` Eli Zaretskii ` (2 more replies) 3 siblings, 3 replies; 765+ messages in thread From: David Kastrup @ 2015-11-15 16:01 UTC (permalink / raw) To: Eli Zaretskii; +Cc: rudalics, jwiegley, rms, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Richard Stallman <rms@gnu.org> >> CC: eliz@gnu.org, rudalics@gmx.at, jwiegley@gmail.com, >> emacs-devel@gnu.org >> Date: Fri, 13 Nov 2015 17:03:10 -0500 >> >> > I think it is quite reasonable _not_ to use wide ints by >> > default on architectures with a 32-bit address space. >> >> +1. > > Faced with such powerful opposition, I guess this now becomes your > decision, John. I can always build my own Emacs with that option; the > question is what we want for the majority of our users on 32-bit > systems. Here is another data point: the code base seems woefully unprepared to actually deal with the resulting ranges. Lisp integers are only converted with macros XINT and XFASTINT as far as I can tell, and git grep XINT shows lots of assignments to variables of type int rather than EMACS_INT. I think that there should be macros XINT, XUINT, XEINT (for EMACS_INT) which trigger a range error when the value does not fit the respective range. Possibly also XLONG and XULONG but I'm not sure we actually have platforms where long/int are different. Some of those uses may well be security problems. Using EMACS_INT everywhere might be inappropriate (where's the point in having array indexes longer than the addressable memory space?) but then we should likely get range errors. Of course, doing this properly might also mean less work for moving to arbitrary-size integers eventually (probably using the Lisp_Int1 tag when the 28-bit range does not suffice), though that one will likely need a lot of converting `eq' -> `eql' in the Lisp code base. But first we should get wide ints behave sensibly when their range exceeds the expected target range. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-15 16:01 ` David Kastrup @ 2015-11-15 19:36 ` Eli Zaretskii 2015-11-15 20:42 ` David Kastrup 2015-11-16 23:17 ` Paul Eggert 2015-11-17 2:47 ` Tom Tromey 2 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-15 19:36 UTC (permalink / raw) To: David Kastrup; +Cc: rudalics, jwiegley, rms, emacs-devel > From: David Kastrup <dak@gnu.org> > Cc: rms@gnu.org, rudalics@gmx.at, emacs-devel@gnu.org, jwiegley@gmail.com > Date: Sun, 15 Nov 2015 17:01:40 +0100 > > Here is another data point: the code base seems woefully unprepared to > actually deal with the resulting ranges. > > Lisp integers are only converted with macros XINT and XFASTINT as far as > I can tell, and > > git grep XINT > > shows lots of assignments to variables of type int rather than > EMACS_INT. If these are real problems, they should have bitten us long ago, in the 64-bit builds, no? There were, indeed, such problems, which prevented using buffers larger than 2GB, but they were solved long ago, when a significant portion of our users moved to 64-bit machines. > I think that there should be macros XINT, XUINT, XEINT (for > EMACS_INT) which trigger a range error when the value does not fit the > respective range. Could be a valuable debugging aid, I think. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-15 19:36 ` Eli Zaretskii @ 2015-11-15 20:42 ` David Kastrup 2015-11-15 21:02 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: David Kastrup @ 2015-11-15 20:42 UTC (permalink / raw) To: Eli Zaretskii; +Cc: rudalics, jwiegley, rms, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: David Kastrup <dak@gnu.org> >> Cc: rms@gnu.org, rudalics@gmx.at, emacs-devel@gnu.org, jwiegley@gmail.com >> Date: Sun, 15 Nov 2015 17:01:40 +0100 >> >> Here is another data point: the code base seems woefully unprepared to >> actually deal with the resulting ranges. >> >> Lisp integers are only converted with macros XINT and XFASTINT as far as >> I can tell, and >> >> git grep XINT >> >> shows lots of assignments to variables of type int rather than >> EMACS_INT. > > If these are real problems, they should have bitten us long ago, in > the 64-bit builds, no? Why? They'll only trigger for cases that exceed a range of 32 bits, and if those cases were other than rare, they'd have rendered the 32-bit builds (which work with 30-bit precision) unusable. However, we never previously had the case that a number which looks fine in Lisp does not transfer into C properly. > There were, indeed, such problems, which prevented using buffers > larger than 2GB, but they were solved long ago, when a significant > portion of our users moved to 64-bit machines. > >> I think that there should be macros XINT, XUINT, XEINT (for >> EMACS_INT) which trigger a range error when the value does not fit >> the respective range. > > Could be a valuable debugging aid, I think. Well, it's probably worth checking what Guilemacs' idea about XINT is since Guile _does_ seamlessly degrade into arbitrary precision integers when exceeding integer precision. So much of the work for supporting arbitrary integers (and converting from Guile/Elisp integers to C integers and back) should probably be in the Guilemacs branch already and there'd be little point in reinventing it separately. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-15 20:42 ` David Kastrup @ 2015-11-15 21:02 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-15 21:02 UTC (permalink / raw) To: David Kastrup; +Cc: rudalics, jwiegley, rms, emacs-devel > From: David Kastrup <dak@gnu.org> > Cc: rms@gnu.org, rudalics@gmx.at, emacs-devel@gnu.org, jwiegley@gmail.com > Date: Sun, 15 Nov 2015 21:42:24 +0100 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> From: David Kastrup <dak@gnu.org> > >> Cc: rms@gnu.org, rudalics@gmx.at, emacs-devel@gnu.org, jwiegley@gmail.com > >> Date: Sun, 15 Nov 2015 17:01:40 +0100 > >> > >> Here is another data point: the code base seems woefully unprepared to > >> actually deal with the resulting ranges. > >> > >> Lisp integers are only converted with macros XINT and XFASTINT as far as > >> I can tell, and > >> > >> git grep XINT > >> > >> shows lots of assignments to variables of type int rather than > >> EMACS_INT. > > > > If these are real problems, they should have bitten us long ago, in > > the 64-bit builds, no? > > Why? Because an int is a 32-bit data type in 64-bit builds as well. So if we use XINT to assign to an int, and the value exceeds INT_MAX, the same problems will happen in both 64-bit builds and in 32-bit builds with wide ints. > They'll only trigger for cases that exceed a range of 32 bits, and > if those cases were other than rare, they'd have rendered the 32-bit > builds (which work with 30-bit precision) unusable. The same considerations apply to 64-bit builds. My point is that these issues, if they exist, are not unique to the 32-bit builds with wide ints, they are with us even without wide ints. > However, we never previously had the case that a number which looks fine > in Lisp does not transfer into C properly. Once again, if we assign an Emacs integer to a C int, we will have the same problems in 64-bit builds. Btw, it's not like we live dangerously there: these issues were extensively scrutinized several years ago, when we lifted the 2GB limit on buffers in 64-bit builds, and all the relevant code was carefully audited and fixed. It is, of course, possible that some new problems crept in, but the basis is sound, both for the 64-bit build and the 32-bit build with wide ints. Bottom line: I don't think there are new problems the 32-bit build with wide ints introduces that aren't with us in the 64-bit builds. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-15 16:01 ` David Kastrup 2015-11-15 19:36 ` Eli Zaretskii @ 2015-11-16 23:17 ` Paul Eggert 2015-11-17 1:34 ` Random832 2015-11-17 12:13 ` David Kastrup 2015-11-17 2:47 ` Tom Tromey 2 siblings, 2 replies; 765+ messages in thread From: Paul Eggert @ 2015-11-16 23:17 UTC (permalink / raw) To: David Kastrup; +Cc: emacs-devel On 11/15/2015 08:01 AM, David Kastrup wrote: > I can tell, and > > git grep XINT > > shows lots of assignments to variables of type int rather than > EMACS_INT. I think that there should be macros XINT, XUINT, XEINT (for > EMACS_INT) which trigger a range error when the value does not fit the > respective range. Possibly also XLONG and XULONG but I'm not sure we > actually have platforms where long/int are different. There's no need XEINT etc., as this work has already been done, using macros like CHECK_TYPE_RANGED_INTEGER to make sure that XINT returns values in range for a C integer type. Also, I sometimes build Emacs with C integer overflow checking enabled, and it runs fine. Really, integer overflow is not a significant problem with --with-wide-int. As Eli says, if it were a problem it'd also be a problem with 64-bit platforms, which it's not. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-16 23:17 ` Paul Eggert @ 2015-11-17 1:34 ` Random832 2015-11-17 3:42 ` Eli Zaretskii 2015-11-17 6:32 ` Paul Eggert 2015-11-17 12:13 ` David Kastrup 1 sibling, 2 replies; 765+ messages in thread From: Random832 @ 2015-11-17 1:34 UTC (permalink / raw) To: emacs-devel Paul Eggert <eggert@cs.ucla.edu> writes: > Really, integer overflow is not a significant problem with > --with-wide-int. As Eli says, if it were a problem it'd also be a > problem with 64-bit platforms, which it's not. I think the issue some people are bringing up is that the concrete cases that would actually trigger the bugs, if there are any (very large files, very large strings, very large buffers) are rare even on 64-bit machines. Sure, it's nice to be _able_ to edit 2GB files, but how many of those does the average user have lying around? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-17 1:34 ` Random832 @ 2015-11-17 3:42 ` Eli Zaretskii 2015-11-17 6:32 ` Paul Eggert 1 sibling, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-17 3:42 UTC (permalink / raw) To: Random832; +Cc: emacs-devel > From: Random832 <random832@fastmail.com> > Date: Mon, 16 Nov 2015 20:34:39 -0500 > > Paul Eggert <eggert@cs.ucla.edu> writes: > > Really, integer overflow is not a significant problem with > > --with-wide-int. As Eli says, if it were a problem it'd also be a > > problem with 64-bit platforms, which it's not. > > I think the issue some people are bringing up is that the concrete cases > that would actually trigger the bugs, if there are any (very large > files, very large strings, very large buffers) are rare even on 64-bit > machines. They are rare, but they have been tested a few years ago, and the bugs found fixed. The people who did that specifically made a point of editing such large files for the purposes of finding and fixing any such bugs. > Sure, it's nice to be _able_ to edit 2GB files, but how many > of those does the average user have lying around? Those who need to look at large log files have to do this every day. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-17 1:34 ` Random832 2015-11-17 3:42 ` Eli Zaretskii @ 2015-11-17 6:32 ` Paul Eggert 2015-11-17 9:08 ` Ulrich Mueller 1 sibling, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-17 6:32 UTC (permalink / raw) To: Random832, emacs-devel Random832 wrote: > Sure, it's nice to be_able_ to edit 2GB files, but how many > of those does the average user have lying around? Without --with-wide-int the limit is roughly 0.5 GB, not 2 GB. Whether this is a problem depends on what sorts of files one typically looks at. These days a goodly number of users do run into larger files. Certainly I do -- usually log or data files. Although I try to keep these files less than 0.5 GB, this can be a pain. And although I can switch to some other text editor to look at an 0.6 GB file, that's awkward, and gives users a bad impression about Emacs's robustness and ease of use. The GNU Coding Standards give advice about whether 32-bit Emacs should default to mishandling 0.6 GB files. They say, "Avoid arbitrary limits on the length or number of _any_ data structure" (emphasis in original). Emacs buffers are a data structure, and --with-wide-int removes a significant and arbitrary limit on their length, so the path forward is reasonably clear here. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-17 6:32 ` Paul Eggert @ 2015-11-17 9:08 ` Ulrich Mueller 2015-11-17 18:42 ` Paul Eggert 2015-11-17 22:58 ` Richard Stallman 0 siblings, 2 replies; 765+ messages in thread From: Ulrich Mueller @ 2015-11-17 9:08 UTC (permalink / raw) To: Paul Eggert; +Cc: Random832, emacs-devel >>>>> On Mon, 16 Nov 2015, Paul Eggert wrote: > The GNU Coding Standards give advice about whether 32-bit Emacs > should default to mishandling 0.6 GB files. They say, "Avoid > arbitrary limits on the length or number of _any_ data structure" > (emphasis in original). But this is about avoiding static allocation. The complete sentence reads: "Avoid arbitrary limits on the length or number of /any/ data structure, including file names, lines, files, and symbols, by allocating all data structures dynamically." > Emacs buffers are a data structure, and --with-wide-int removes a > significant and arbitrary limit on their length, so the path forward > is reasonably clear here. A limit imposed by the machine's word size doesn't seem so arbitrary, if it can only be surpassed with a significant performance penalty. Ulrich ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-17 9:08 ` Ulrich Mueller @ 2015-11-17 18:42 ` Paul Eggert 2015-11-17 20:32 ` Ulrich Mueller 2015-11-17 22:58 ` Richard Stallman 1 sibling, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-17 18:42 UTC (permalink / raw) To: Ulrich Mueller; +Cc: Random832, emacs-devel On 11/17/2015 01:08 AM, Ulrich Mueller wrote: > A limit imposed by the machine's word size doesn't seem so arbitrary Yes, quite so, and that's what --with-wide-int does: it changes Emacs so that buffer sizes are limited by the machine word size, instead of being limited by some arbitrary truncation of that word size, a truncation not imposed by the machine. > if it can only be surpassed with a significant performance penalty That's too strict and we have never been that strict. On the contrary we regularly make changes to Emacs that impose a significant penalty -- i.e., a penalty that can be measured in a statistically significant way. Even the GNU Coding Standard's guideline about allocating data dynamically can impose a significant performance penalty compared to static allocation, in many cases. But that's OK. We can impose a small (albeit significant) performance penalty if this removes an important arbitrary limit on a data structure size. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-17 18:42 ` Paul Eggert @ 2015-11-17 20:32 ` Ulrich Mueller 2015-11-18 16:32 ` Achim Gratz 0 siblings, 1 reply; 765+ messages in thread From: Ulrich Mueller @ 2015-11-17 20:32 UTC (permalink / raw) To: Paul Eggert; +Cc: Random832, emacs-devel >>>>> On Tue, 17 Nov 2015, Paul Eggert wrote: > On 11/17/2015 01:08 AM, Ulrich Mueller wrote: >> A limit imposed by the machine's word size doesn't seem so arbitrary > Yes, quite so, and that's what --with-wide-int does: it changes Emacs so > that buffer sizes are limited by the machine word size, instead of being > limited by some arbitrary truncation of that word size, a truncation not > imposed by the machine. The maximum sizes aren't much increased though, as the limit of process address space will be hit soon after. Which for a 32-bit Linux typically is somewhere between 2 and 3 GiB. So yes, there are some file sizes which can be edited in addition, but that range is rather narrow. I still think that --without-wide-int is the more reasonable default. Users who need those big buffers or files can easily flip the option. Ulrich ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-17 20:32 ` Ulrich Mueller @ 2015-11-18 16:32 ` Achim Gratz 2015-11-18 17:10 ` David Kastrup 2015-11-18 17:38 ` Eli Zaretskii 0 siblings, 2 replies; 765+ messages in thread From: Achim Gratz @ 2015-11-18 16:32 UTC (permalink / raw) To: emacs-devel Ulrich Mueller writes: > I still think that --without-wide-int is the more reasonable default. I beg to differ. > Users who need those big buffers or files can easily flip the option. That's not a good argument to base that decision on anyway. The trigger for making that switch on all my old 32bit machines was that you can't represent an awful lot of dates on any modern system otherwise. So the decision should really be based on what size time_t is, IMHO. Regards, Achim. -- +<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+ SD adaptations for Waldorf Q V3.00R3 and Q+ V3.54R2: http://Synth.Stromeko.net/Downloads.html#WaldorfSDada ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-18 16:32 ` Achim Gratz @ 2015-11-18 17:10 ` David Kastrup 2015-11-18 17:38 ` Eli Zaretskii 1 sibling, 0 replies; 765+ messages in thread From: David Kastrup @ 2015-11-18 17:10 UTC (permalink / raw) To: Achim Gratz; +Cc: emacs-devel Achim Gratz <Stromeko@nexgo.de> writes: > Ulrich Mueller writes: >> I still think that --without-wide-int is the more reasonable default. > > I beg to differ. > >> Users who need those big buffers or files can easily flip the option. > > That's not a good argument to base that decision on anyway. The > trigger for making that switch on all my old 32bit machines was that > you can't represent an awful lot of dates on any modern system > otherwise. Huh? current-time is a built-in function in ‘C source code’. (current-time) Return the current time, as the number of seconds since 1970-01-01 00:00:00. The time is returned as a list of integers (HIGH LOW USEC PSEC). HIGH has the most significant bits of the seconds, while LOW has the least significant 16 bits. USEC and PSEC are the microsecond and picosecond counts. [back] float-time is a built-in function in ‘C source code’. (float-time &optional SPECIFIED-TIME) Return the current time, as a float number of seconds since the epoch. If SPECIFIED-TIME is given, it is the time to convert to float instead of the current time. The argument should have the form (HIGH LOW) or (HIGH LOW USEC) or (HIGH LOW USEC PSEC). Thus, you can use times from ‘current-time’ and from ‘file-attributes’. SPECIFIED-TIME can also have the form (HIGH . LOW), but this is considered obsolete. WARNING: Since the result is floating point, it may not be exact. If precise time stamps are required, use either ‘current-time’, or (if you need time as a string) ‘format-time-string’. [back] > So the decision should really be based on what size time_t is, IMHO. I don't see the point since all time representations of Emacs are long established in a form that works fine with 24 bits of precision. So time_t is a "solved problem" at the current point of time. I don't see that tampering with it makes any sense before Emacs gains arbitrary precision integers: it seems pointless to tie time manipulations to some particular machine precision. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-18 16:32 ` Achim Gratz 2015-11-18 17:10 ` David Kastrup @ 2015-11-18 17:38 ` Eli Zaretskii 1 sibling, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-18 17:38 UTC (permalink / raw) To: Achim Gratz; +Cc: emacs-devel > From: Achim Gratz <Stromeko@nexgo.de> > Date: Wed, 18 Nov 2015 17:32:10 +0100 > > The trigger for making that switch on all my old 32bit machines was > that you can't represent an awful lot of dates on any modern system > otherwise. So the decision should really be based on what size > time_t is, IMHO. Maybe I misunderstand you, but the --with-wide-int option doesn't (and cannot) change anything wrt the time_t type. If it was a 32-bit type without wide ints, it will still be a 32-bit type with them. Or did you mean something else? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-17 9:08 ` Ulrich Mueller 2015-11-17 18:42 ` Paul Eggert @ 2015-11-17 22:58 ` Richard Stallman 1 sibling, 0 replies; 765+ messages in thread From: Richard Stallman @ 2015-11-17 22:58 UTC (permalink / raw) To: Ulrich Mueller; +Cc: random832, eggert, emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > A limit imposed by the machine's word size doesn't seem so arbitrary, > if it can only be surpassed with a significant performance penalty. That is right. -- Dr Richard Stallman President, Free Software Foundation (gnu.org, fsf.org) Internet Hall-of-Famer (internethalloffame.org) Skype: No way! See stallman.org/skype.html. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-16 23:17 ` Paul Eggert 2015-11-17 1:34 ` Random832 @ 2015-11-17 12:13 ` David Kastrup 2015-11-17 18:32 ` Paul Eggert 1 sibling, 1 reply; 765+ messages in thread From: David Kastrup @ 2015-11-17 12:13 UTC (permalink / raw) To: Paul Eggert; +Cc: emacs-devel Paul Eggert <eggert@cs.ucla.edu> writes: > On 11/15/2015 08:01 AM, David Kastrup wrote: >> I can tell, and >> >> git grep XINT >> >> shows lots of assignments to variables of type int rather than >> EMACS_INT. I think that there should be macros XINT, XUINT, XEINT (for >> EMACS_INT) which trigger a range error when the value does not fit the >> respective range. Possibly also XLONG and XULONG but I'm not sure we >> actually have platforms where long/int are different. > > There's no need XEINT etc., as this work has already been done, using > macros like CHECK_TYPE_RANGED_INTEGER to make sure that XINT returns > values in range for a C integer type. This has to be called explicitly. There are several consequences of the current choices: for one thing, one cannot enable C compiler warnings about too small integer types since any assignment of XINT to an int will trigger such a warning, making them useless for detecting actual problems. As one consequence, every single use of XINT needs manual code review. As another consequence, we'll have to redo all of the code review when moving to Guile and/or arbitrary precision integers since the current code obviously assumes that EMACS_INT is large enough for any integer value representable in Lisp. Guile has all of -- C Function: char scm_to_char (SCM x) -- C Function: signed char scm_to_schar (SCM x) -- C Function: unsigned char scm_to_uchar (SCM x) -- C Function: short scm_to_short (SCM x) -- C Function: unsigned short scm_to_ushort (SCM x) -- C Function: int scm_to_int (SCM x) -- C Function: unsigned int scm_to_uint (SCM x) -- C Function: long scm_to_long (SCM x) -- C Function: unsigned long scm_to_ulong (SCM x) -- C Function: long long scm_to_long_long (SCM x) -- C Function: unsigned long long scm_to_ulong_long (SCM x) -- C Function: size_t scm_to_size_t (SCM x) -- C Function: ssize_t scm_to_ssize_t (SCM x) -- C Function: scm_t_ptrdiff scm_to_ptrdiff_t (SCM x) -- C Function: scm_t_int8 scm_to_int8 (SCM x) -- C Function: scm_t_uint8 scm_to_uint8 (SCM x) -- C Function: scm_t_int16 scm_to_int16 (SCM x) -- C Function: scm_t_uint16 scm_to_uint16 (SCM x) -- C Function: scm_t_int32 scm_to_int32 (SCM x) -- C Function: scm_t_uint32 scm_to_uint32 (SCM x) -- C Function: scm_t_int64 scm_to_int64 (SCM x) -- C Function: scm_t_uint64 scm_to_uint64 (SCM x) -- C Function: scm_t_intmax scm_to_intmax (SCM x) -- C Function: scm_t_uintmax scm_to_uintmax (SCM x) When X represents an exact integer that fits into the indicated C type, return that integer. Else signal an error, either a ‘wrong-type’ error when X is not an exact integer, or an ‘out-of-range’ error when it doesn’t fit the given range. The functions ‘scm_to_long_long’, ‘scm_to_ulong_long’, ‘scm_to_int64’, and ‘scm_to_uint64’ are only available when the corresponding types are. What does that mean? For one thing it means that the C compiler can have all of its warnings for losing significant bits enabled meaningfully. For another it means that converting a Lisp integer to something used is a C routine will either succeed or throw an error. The reverse conversions all succeed, and naturally without ever losing any precision (as opposed to our current conversion which, I think, silently drops a few bits from the top of any EMACS_INT when converting to Lisp_Object . Integer overflows are a rather popular source of security vulnerabilities and/or crashes, so having them under control by default is a good idea and means that we don't need to start rereviewing everything whenever our integer representation changes. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-17 12:13 ` David Kastrup @ 2015-11-17 18:32 ` Paul Eggert 0 siblings, 0 replies; 765+ messages in thread From: Paul Eggert @ 2015-11-17 18:32 UTC (permalink / raw) To: David Kastrup; +Cc: emacs-devel On 11/17/2015 04:13 AM, David Kastrup wrote: > Integer overflows are a rather popular source of security > vulnerabilities and/or crashes, so having them under control by default > is a good idea Yes, yes, all that's good, but that set of primitives (scm_t_uint16 scm_to_uint16 etc.), while an impressively long laundry list, doesn't solve the problem or even (to be honest) inspire much confidence that the problem is even understood. How does one convert a Guile integer to a time_t? Or to an off_t? Or to a nonnegative ptrdiff_t? None of the primitives you mention seem to address the typical problems I run into when auditing Emacs source code. Far more useful is a small set of generic primitives that one can use to convert a Lisp integer to any system integer type, checking for overflow in the process. Emacs has that already. I suppose something like that could be built in Guile too. If so, then all we'd need to do is port the existing Emacs generic macros to run atop Guile, and no further code review should be needed. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-15 16:01 ` David Kastrup 2015-11-15 19:36 ` Eli Zaretskii 2015-11-16 23:17 ` Paul Eggert @ 2015-11-17 2:47 ` Tom Tromey 2 siblings, 0 replies; 765+ messages in thread From: Tom Tromey @ 2015-11-17 2:47 UTC (permalink / raw) To: David Kastrup; +Cc: rudalics, Eli Zaretskii, emacs-devel, rms, jwiegley David> Of course, doing this properly might also mean less work for moving to David> arbitrary-size integers eventually (probably using the Lisp_Int1 tag David> when the 28-bit range does not suffice), though that one will likely David> need a lot of converting `eq' -> `eql' in the Lisp code base. Preserving the eq/eql distinction seems pointless. It's a leaky abstraction with no real gain for Emacs Lisp developers. I think it's better to just make `eq' treat bignums as values, and then don't bother changing all the exist elisp. Tom ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-13 22:03 ` Richard Stallman 2015-11-14 8:43 ` Eli Zaretskii @ 2015-11-20 2:20 ` Stefan Monnier 2015-11-20 8:44 ` Eli Zaretskii 2015-11-20 16:27 ` John Wiegley 1 sibling, 2 replies; 765+ messages in thread From: Stefan Monnier @ 2015-11-20 2:20 UTC (permalink / raw) To: emacs-devel >> I think it is quite reasonable _not_ to use wide ints by >> default on architectures with a 32-bit address space. > +1. Another +1 here. My impression from here is that 32bit userlands are becoming the minority anyway, so they're mostly used on machines with limited resources (CPU, cache, RAM). In this context, I think it's wrong to use up more CPU, RAM and cache by default all the time, just on the off-chance that the user will want to view a file that happens to fall just within the 512MB to 2GB window. Would it have ever helped me to build with wide-int? Yes, maybe a couple of time over the last few years. But those are dwarfed by the tens of times that this would have made no difference because the file was greater than 2GB anyway. For those rare >512MB cases, there's GNU ELPA's "vlf" package. If we care about users being able to open very large files on 32bit systems, we should improve that package rather than enable wide-ints by default. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-20 2:20 ` Stefan Monnier @ 2015-11-20 8:44 ` Eli Zaretskii 2015-11-20 16:27 ` John Wiegley 1 sibling, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-20 8:44 UTC (permalink / raw) To: Stefan Monnier, John Wiegley; +Cc: emacs-devel > From: Stefan Monnier <monnier@iro.umontreal.ca> > Date: Thu, 19 Nov 2015 21:20:16 -0500 > > >> I think it is quite reasonable _not_ to use wide ints by > >> default on architectures with a 32-bit address space. > > +1. > > Another +1 here. John, it's time to make the decision. You have all the opinions and their rationales. If you have more questions, please ask. But we should conclude this longish discussion at some point; now sounds as good time as any. Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-20 2:20 ` Stefan Monnier 2015-11-20 8:44 ` Eli Zaretskii @ 2015-11-20 16:27 ` John Wiegley 1 sibling, 0 replies; 765+ messages in thread From: John Wiegley @ 2015-11-20 16:27 UTC (permalink / raw) To: Stefan Monnier; +Cc: emacs-devel >>>>> Stefan Monnier <monnier@iro.umontreal.ca> writes: > For those rare >512MB cases, there's GNU ELPA's "vlf" package. If we care > about users being able to open very large files on 32bit systems, we should > improve that package rather than enable wide-ints by default. >>>>> Eli Zaretskii <eliz@gnu.org> writes: > John, it's time to make the decision. You have all the opinions and their > rationales. If you have more questions, please ask. But we should conclude > this longish discussion at some point; now sounds as good time as any. I hold with Stefan's reasoning. We should not change --with-wide-int to become the default. --with-wide-int as a default benefits one group (most users on 32-bit platforms) at the cost of another (users on 32-bit platforms whom it would slow down, and who would need to disable it). Also, it does not affect those who are becoming the predominant audience (users on 64-bit platforms). Thus, I don't see it as a necessary change, especially if "vlf" is a viable alternative. Lastly, 32-bit power users can configure using --with-wide-int. Making this change requires further tests, documentation on how to disable wide-ints (and why), and changes the status quo without demonstrating a compelling benefit. If it had no costs at all, I'd say it was the "right thing to do"; but it's not zero cost, and the benefit does not appear to justify the change. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-11-11 18:43 ` Eli Zaretskii 2015-11-12 8:23 ` martin rudalics @ 2015-11-12 16:29 ` Juanma Barranquero 1 sibling, 0 replies; 765+ messages in thread From: Juanma Barranquero @ 2015-11-12 16:29 UTC (permalink / raw) To: Eli Zaretskii; +Cc: John Wiegley, Emacs developers [-- Attachment #1: Type: text/plain, Size: 330 bytes --] On Wed, Nov 11, 2015 at 7:43 PM, Eli Zaretskii <eliz@gnu.org> wrote: > Based on this, I'd like to turn --with-wide-int on by default. Any > last-minute objections? I've been building with --with-wide-int for the past few weeks with no ill effect. My Emacs is slow, but as I build with many checks enabled, it is always slow... [-- Attachment #2: Type: text/html, Size: 459 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 8:15 ` Eli Zaretskii 2015-10-16 8:27 ` Paul Eggert @ 2015-10-16 8:28 ` Juanma Barranquero 2015-10-16 8:40 ` Paul Eggert 1 sibling, 1 reply; 765+ messages in thread From: Juanma Barranquero @ 2015-10-16 8:28 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Paul Eggert, Emacs developers [-- Attachment #1: Type: text/plain, Size: 600 bytes --] On Fri, Oct 16, 2015 at 10:15 AM, Eli Zaretskii <eliz@gnu.org> wrote: > > > Cc: emacs-devel@gnu.org > > From: Paul Eggert <eggert@cs.ucla.edu> > > Date: Fri, 16 Oct 2015 01:03:15 -0700 > > I typically use 64-bit platforms nowadays, where the issue is moot. When I do > > use 32-bit platforms, I normally configure --with-wide-int. There is roughly a > > 30% CPU hit and maybe a 60% hit on virtual memory, but it's worth it to me (I > > normally don't notice the difference). > > Thanks, that about summarizes what I see here as well. Are we talking of a 30% CPU hit in non-optimized builds, right? [-- Attachment #2: Type: text/html, Size: 869 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 8:28 ` Juanma Barranquero @ 2015-10-16 8:40 ` Paul Eggert 0 siblings, 0 replies; 765+ messages in thread From: Paul Eggert @ 2015-10-16 8:40 UTC (permalink / raw) To: Juanma Barranquero, Eli Zaretskii; +Cc: Emacs developers Juanma Barranquero wrote: > Are we talking of a 30% CPU hit in non-optimized builds, right? No, I was measuring with -O2. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 8:03 ` Making --with-wide-int the default Paul Eggert 2015-10-16 8:15 ` Eli Zaretskii @ 2015-10-16 8:18 ` David Kastrup 2015-10-16 8:49 ` Paul Eggert ` (2 more replies) 1 sibling, 3 replies; 765+ messages in thread From: David Kastrup @ 2015-10-16 8:18 UTC (permalink / raw) To: Paul Eggert; +Cc: Juanma Barranquero, Eli Zaretskii, emacs-devel Paul Eggert <eggert@cs.ucla.edu> writes: > Eli Zaretskii wrote: >> To make it the default for all 32-bit builds, we should make sure it >> works well on the other supported platforms. Perhaps Paul could tell >> which platforms he found this to work on, and then we could decide. > > --with-wide-int is not the default because Stefan was worried about > its performance implications on older, slower 32-bit machines (such as > Stefan's and/or RMS's laptops at the time, if I recall > correctly). There shouldn't be any correctness problem with it; it's a > performance issue. > > I typically use 64-bit platforms nowadays, where the issue is > moot. When I do use 32-bit platforms, I normally configure > --with-wide-int. There is roughly a 30% CPU hit and maybe a 60% hit on > virtual memory, but it's worth it to me (I normally don't notice the > difference). Ugh. That would be quite noticeable to me. While I build my own Emacs, having to drag around a bundle of homebrewn options just to get sensible behavior does not appeal to me. Instead of going to 64-bit unilaterally it would seem to make more sense to me to degrade gracefully into gmp. GUILE does that, I think that XEmacs or SXEmacs can do it, and it's usual for Lisp implementations. That leaves the memory cost for the 0.01% of uses (if at all) that need it. Of course, with a CPU cost hit (which in the common case of addition/subtraction at natural width would amount to checking the overflow bit afterwards). Would also make for a nice speedup of calc (which implements everything the hard way via small ints and lists, the Emacs 18 way: David Gillespie dropped off the Earth before I could manage to have him dig up his Emacs 19 modifications using floating point when available). If one can disentangle the internals appropriately. But that's probably easier for using gmp transparently than for using FP as first approximation. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 8:18 ` David Kastrup @ 2015-10-16 8:49 ` Paul Eggert 2015-10-16 9:00 ` David Kastrup 2015-10-16 9:06 ` Eli Zaretskii 2015-10-16 15:53 ` Stephen J. Turnbull 2 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-10-16 8:49 UTC (permalink / raw) To: David Kastrup; +Cc: Juanma Barranquero, Eli Zaretskii, emacs-devel David Kastrup wrote: > Instead of going to 64-bit unilaterally it would seem to make more sense > to me to degrade gracefully into gmp. GUILE does that, I think that > XEmacs or SXEmacs can do it, and it's usual for Lisp implementations. In my spare time I've been working on something along those lines, but it's not at all ready for prime time. Some Emacs code assumes that integer overflow silently wraps around, and another common assumption is that integers are = if and only if they are eq. Bignums violate both assumptions. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 8:49 ` Paul Eggert @ 2015-10-16 9:00 ` David Kastrup 0 siblings, 0 replies; 765+ messages in thread From: David Kastrup @ 2015-10-16 9:00 UTC (permalink / raw) To: Paul Eggert; +Cc: Juanma Barranquero, Eli Zaretskii, emacs-devel Paul Eggert <eggert@cs.ucla.edu> writes: > David Kastrup wrote: >> Instead of going to 64-bit unilaterally it would seem to make more sense >> to me to degrade gracefully into gmp. GUILE does that, I think that >> XEmacs or SXEmacs can do it, and it's usual for Lisp implementations. > > In my spare time I've been working on something along those lines, but > it's not at all ready for prime time. Some Emacs code assumes that > integer overflow silently wraps around, and another common assumption > is that integers are = if and only if they are eq. Bignums violate > both assumptions. Yes. The LilyPond code base (running on GUILE) is riddled with code that assumes integers are eq. Fixing that is slow work. On the other hand, the unfixed code does not really work worse than Emacs' code works now: neither cannot handle values larger than standard integers. In order to get the same semantics as now, a GMP number should be converted back to a native LISP integer whenever it's small enough again. That provides some slight overhead for arithmetic that had to happen in GMP, but then we are outside of the main performance characteristic anyway. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 8:18 ` David Kastrup 2015-10-16 8:49 ` Paul Eggert @ 2015-10-16 9:06 ` Eli Zaretskii 2015-10-16 9:18 ` David Kastrup 2015-10-16 15:53 ` Stephen J. Turnbull 2 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-10-16 9:06 UTC (permalink / raw) To: David Kastrup; +Cc: lekktu, eggert, emacs-devel > From: David Kastrup <dak@gnu.org> > Cc: Eli Zaretskii <eliz@gnu.org>, Juanma Barranquero <lekktu@gmail.com>, emacs-devel@gnu.org > Date: Fri, 16 Oct 2015 10:18:26 +0200 > > Instead of going to 64-bit unilaterally it would seem to make more sense > to me to degrade gracefully into gmp. How can GMP help extend the maximum size of buffers and strings beyond what a 32-bit EMACS_INT allows? And how can GMP be faster than (or even close to) the native 64-bit integral types supported by the C compiler? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 9:06 ` Eli Zaretskii @ 2015-10-16 9:18 ` David Kastrup 2015-10-16 10:09 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: David Kastrup @ 2015-10-16 9:18 UTC (permalink / raw) To: Eli Zaretskii; +Cc: lekktu, eggert, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: David Kastrup <dak@gnu.org> >> Cc: Eli Zaretskii <eliz@gnu.org>, Juanma Barranquero >> <lekktu@gmail.com>, emacs-devel@gnu.org >> Date: Fri, 16 Oct 2015 10:18:26 +0200 >> >> Instead of going to 64-bit unilaterally it would seem to make more sense >> to me to degrade gracefully into gmp. > > How can GMP help extend the maximum size of buffers and strings beyond > what a 32-bit EMACS_INT allows? By choosing an appropriate data type for representing buffer/string sizes in C and converting back-and-forth from the Lisp type as needed. Pretty much the same way we do it now. I think it would be a reasonable restriction to keep to 2GB size of strings and buffers when working with a 32bit executable. That's what people expect on a 32-bit architecture. > And how can GMP be faster than (or even close to) the native 64-bit > integral types supported by the C compiler? GMP will not get to see the vast majority of numbers passing through Emacs, and on a 32-bit system 32-bit integral types will be faster than 64-bit integral types. When you are editing gigabyte files, at some point of time, the Lisp representation of the respective offsets in the high part of the buffer will become the responsibility of GMP, yes. I'm not worried about that. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 9:18 ` David Kastrup @ 2015-10-16 10:09 ` Eli Zaretskii 2015-10-16 10:27 ` David Kastrup 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-10-16 10:09 UTC (permalink / raw) To: David Kastrup; +Cc: lekktu, eggert, emacs-devel > From: David Kastrup <dak@gnu.org> > Cc: eggert@cs.ucla.edu, lekktu@gmail.com, emacs-devel@gnu.org > Date: Fri, 16 Oct 2015 11:18:31 +0200 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> From: David Kastrup <dak@gnu.org> > >> Cc: Eli Zaretskii <eliz@gnu.org>, Juanma Barranquero > >> <lekktu@gmail.com>, emacs-devel@gnu.org > >> Date: Fri, 16 Oct 2015 10:18:26 +0200 > >> > >> Instead of going to 64-bit unilaterally it would seem to make more sense > >> to me to degrade gracefully into gmp. > > > > How can GMP help extend the maximum size of buffers and strings beyond > > what a 32-bit EMACS_INT allows? > > By choosing an appropriate data type for representing buffer/string > sizes in C and converting back-and-forth from the Lisp type as needed. > Pretty much the same way we do it now. Sorry, I don't foollow: what "appropriate data type"? Would that be 'long long'? If so, that's exactly what we do now, which you say is "going to 64-bit unilaterally". What am I missing? > I think it would be a reasonable restriction to keep to 2GB size of > strings and buffers when working with a 32bit executable. That's > what people expect on a 32-bit architecture. That's what we have now in 32-bit builds --with-wide-int. So I'm not sure why you mention that as some kind of change related to this discussion. > > And how can GMP be faster than (or even close to) the native 64-bit > > integral types supported by the C compiler? > > GMP will not get to see the vast majority of numbers passing through > Emacs, and on a 32-bit system 32-bit integral types will be faster than > 64-bit integral types. > > When you are editing gigabyte files, at some point of time, the Lisp > representation of the respective offsets in the high part of the buffer > will become the responsibility of GMP, yes. I'm not worried about that. I don't understand. C doesn't have dynamic types. If the variable that holds buffer positions needs to support 61-bit offsets, it will have to be a 64-bit integral data type from the get-go. And having 61-bit integers for integer arithmetics is also a valuable feature. So the EMACS_INT type will have to be able to support that. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 10:09 ` Eli Zaretskii @ 2015-10-16 10:27 ` David Kastrup 2015-10-16 13:20 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: David Kastrup @ 2015-10-16 10:27 UTC (permalink / raw) To: Eli Zaretskii; +Cc: lekktu, eggert, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: David Kastrup <dak@gnu.org> >> Cc: eggert@cs.ucla.edu, lekktu@gmail.com, emacs-devel@gnu.org >> Date: Fri, 16 Oct 2015 11:18:31 +0200 >> >> Eli Zaretskii <eliz@gnu.org> writes: >> >> >> From: David Kastrup <dak@gnu.org> >> >> Cc: Eli Zaretskii <eliz@gnu.org>, Juanma Barranquero >> >> <lekktu@gmail.com>, emacs-devel@gnu.org >> >> Date: Fri, 16 Oct 2015 10:18:26 +0200 >> >> >> >> Instead of going to 64-bit unilaterally it would seem to make more sense >> >> to me to degrade gracefully into gmp. >> > >> > How can GMP help extend the maximum size of buffers and strings beyond >> > what a 32-bit EMACS_INT allows? >> >> By choosing an appropriate data type for representing buffer/string >> sizes in C and converting back-and-forth from the Lisp type as needed. >> Pretty much the same way we do it now. > > Sorry, I don't foollow: what "appropriate data type"? Would that be > 'long long'? If so, that's exactly what we do now, which you say is > "going to 64-bit unilaterally". What am I missing? A change in the size of the Lisp data type. >> I think it would be a reasonable restriction to keep to 2GB size of >> strings and buffers when working with a 32bit executable. That's >> what people expect on a 32-bit architecture. > > That's what we have now in 32-bit builds --with-wide-int. So I'm not > sure why you mention that as some kind of change related to this > discussion. Isn't that also changing the size of a Lisp cell? And of integer arithmetic? >> When you are editing gigabyte files, at some point of time, the Lisp >> representation of the respective offsets in the high part of the >> buffer will become the responsibility of GMP, yes. I'm not worried >> about that. > > I don't understand. C doesn't have dynamic types. But Lisp does. > If the variable that holds buffer positions needs to support 61-bit > offsets, it will have to be a 64-bit integral data type from the > get-go. I repeat: we are talking about a 32-bit binary where restricting buffer and string size to 32bit offsets would be reasonable and expected. But even if we assume that we want to support some larger size in the C parts, that's just the matter of choosing a different type and a different conversion from Lisp to C. GUILE has all of -- C Function: char scm_to_char (SCM x) -- C Function: signed char scm_to_schar (SCM x) -- C Function: unsigned char scm_to_uchar (SCM x) -- C Function: short scm_to_short (SCM x) -- C Function: unsigned short scm_to_ushort (SCM x) -- C Function: int scm_to_int (SCM x) -- C Function: unsigned int scm_to_uint (SCM x) -- C Function: long scm_to_long (SCM x) -- C Function: unsigned long scm_to_ulong (SCM x) -- C Function: long long scm_to_long_long (SCM x) -- C Function: unsigned long long scm_to_ulong_long (SCM x) -- C Function: size_t scm_to_size_t (SCM x) -- C Function: ssize_t scm_to_ssize_t (SCM x) -- C Function: scm_t_ptrdiff scm_to_ptrdiff_t (SCM x) -- C Function: scm_t_int8 scm_to_int8 (SCM x) -- C Function: scm_t_uint8 scm_to_uint8 (SCM x) -- C Function: scm_t_int16 scm_to_int16 (SCM x) -- C Function: scm_t_uint16 scm_to_uint16 (SCM x) -- C Function: scm_t_int32 scm_to_int32 (SCM x) -- C Function: scm_t_uint32 scm_to_uint32 (SCM x) -- C Function: scm_t_int64 scm_to_int64 (SCM x) -- C Function: scm_t_uint64 scm_to_uint64 (SCM x) -- C Function: scm_t_intmax scm_to_intmax (SCM x) -- C Function: scm_t_uintmax scm_to_uintmax (SCM x) When X represents an exact integer that fits into the indicated C type, return that integer. Else signal an error, either a ‘wrong-type’ error when X is not an exact integer, or an ‘out-of-range’ error when it doesn’t fit the given range. The functions ‘scm_to_long_long’, ‘scm_to_ulong_long’, ‘scm_to_int64’, and ‘scm_to_uint64’ are only available when the corresponding types are. Choose a C type of your choosing for dealing with buffer offsets, create aliases for its conversions, and you are good to go. The Lisp side supports arbitrary sizes, and the actual C-side limits (rather than something like 26 bits or 29 bits or 30 bits or 61 bits) are established when converting from Lisp types. > And having 61-bit integers for integer arithmetics is also a valuable > feature. 61-bit is some arbitrary junk number. Transparently degrading from 29-bits to gmp numbers means that there are no arbitrary limits (or at least you are unlikely to hit them) and the performance for the vast majority of cases will be 29-bit performance. > So the EMACS_INT type will have to be able to support that. I don't see why when one can use GMP (which effectively uses the same kind arithmetic for 61-bit numbers as C does but does not stop there). -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 10:27 ` David Kastrup @ 2015-10-16 13:20 ` Eli Zaretskii 2015-10-16 14:03 ` David Kastrup 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-10-16 13:20 UTC (permalink / raw) To: David Kastrup; +Cc: lekktu, eggert, emacs-devel > From: David Kastrup <dak@gnu.org> > Cc: eggert@cs.ucla.edu, lekktu@gmail.com, emacs-devel@gnu.org > Date: Fri, 16 Oct 2015 12:27:04 +0200 > > >> > How can GMP help extend the maximum size of buffers and strings beyond > >> > what a 32-bit EMACS_INT allows? > >> > >> By choosing an appropriate data type for representing buffer/string > >> sizes in C and converting back-and-forth from the Lisp type as needed. > >> Pretty much the same way we do it now. > > > > Sorry, I don't foollow: what "appropriate data type"? Would that be > > 'long long'? If so, that's exactly what we do now, which you say is > > "going to 64-bit unilaterally". What am I missing? > > A change in the size of the Lisp data type. We are talking about the _implementation_ of Lisp data types, i.e. about the underlying C data types. What am I missing on that level? > >> I think it would be a reasonable restriction to keep to 2GB size of > >> strings and buffers when working with a 32bit executable. That's > >> what people expect on a 32-bit architecture. > > > > That's what we have now in 32-bit builds --with-wide-int. So I'm not > > sure why you mention that as some kind of change related to this > > discussion. > > Isn't that also changing the size of a Lisp cell? And of integer > arithmetic? Part of it, yes. But since a Lisp cell can hold buffer or string position, what else can you expect? > >> When you are editing gigabyte files, at some point of time, the Lisp > >> representation of the respective offsets in the high part of the > >> buffer will become the responsibility of GMP, yes. I'm not worried > >> about that. > > > > I don't understand. C doesn't have dynamic types. > > But Lisp does. I was talking about C implementation of Lisp types. > > If the variable that holds buffer positions needs to support 61-bit > > offsets, it will have to be a 64-bit integral data type from the > > get-go. > > I repeat: we are talking about a 32-bit binary where restricting buffer > and string size to 32bit offsets would be reasonable and expected. You cannot have full 32-bit offsets without enlarging the width of a Lisp integer. We could use 34 or 35-bit numbers, but that would be slower than using a 64-bit 'long long'. > Choose a C type of your choosing for dealing with buffer offsets, create > aliases for its conversions, and you are good to go. We _have_ chosen: it's a 64-bit 'long long'. What do you suggest to choose instead? Any suggested type should be representable as an Emacs integer. > > And having 61-bit integers for integer arithmetics is also a valuable > > feature. > > 61-bit is some arbitrary junk number. Transparently degrading from > 29-bits to gmp numbers means that there are no arbitrary limits (or at > least you are unlikely to hit them) and the performance for the vast > majority of cases will be 29-bit performance. I don't understand how you intend to "transparently degrade" in the implementation of '+', for example. Are you going to test each argument for whether it fits into 32-bit limits, and if so, invoke 32-bit arithmetics, else 64-bit arithmetics? If so, I'm quite sure the test will steal cycles that will make this slower than just always using 64-bit arithmetics. If you mean something else, can you show some C code that would demonstrate your ideas? > > So the EMACS_INT type will have to be able to support that. > > I don't see why when one can use GMP (which effectively uses the same > kind arithmetic for 61-bit numbers as C does but does not stop there). Because calling a GMP function will most probably yield slower code than if we let the compiler emit a few instructions required for 64-bit arithmetics. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 13:20 ` Eli Zaretskii @ 2015-10-16 14:03 ` David Kastrup 2015-10-16 16:01 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: David Kastrup @ 2015-10-16 14:03 UTC (permalink / raw) To: Eli Zaretskii; +Cc: lekktu, eggert, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: David Kastrup <dak@gnu.org> >> Cc: eggert@cs.ucla.edu, lekktu@gmail.com, emacs-devel@gnu.org >> Date: Fri, 16 Oct 2015 12:27:04 +0200 >> >> >> > How can GMP help extend the maximum size of buffers and strings beyond >> >> > what a 32-bit EMACS_INT allows? >> >> >> >> By choosing an appropriate data type for representing buffer/string >> >> sizes in C and converting back-and-forth from the Lisp type as needed. >> >> Pretty much the same way we do it now. >> > >> > Sorry, I don't foollow: what "appropriate data type"? Would that be >> > 'long long'? If so, that's exactly what we do now, which you say is >> > "going to 64-bit unilaterally". What am I missing? >> >> A change in the size of the Lisp data type. > > We are talking about the _implementation_ of Lisp data types, > i.e. about the underlying C data types. What am I missing on that > level? You are assuming that the C data type used for working with buffer/string position is the same as the type of a Lisp cell. >> >> I think it would be a reasonable restriction to keep to 2GB size of >> >> strings and buffers when working with a 32bit executable. That's >> >> what people expect on a 32-bit architecture. >> > >> > That's what we have now in 32-bit builds --with-wide-int. So I'm not >> > sure why you mention that as some kind of change related to this >> > discussion. >> >> Isn't that also changing the size of a Lisp cell? And of integer >> arithmetic? > > Part of it, yes. But since a Lisp cell can hold buffer or string > position, what else can you expect? That buffer or string positions not representable in the 29 bits or so available for integers in a Lisp cell are instead represented using a gpm number for which there is a reference in the Lisp cell. >> >> When you are editing gigabyte files, at some point of time, the >> >> Lisp representation of the respective offsets in the high part of >> >> the buffer will become the responsibility of GMP, yes. I'm not >> >> worried about that. >> > >> > I don't understand. C doesn't have dynamic types. >> >> But Lisp does. > > I was talking about C implementation of Lisp types. You are apparently unable to deal with the concept of a Lisp type being represented by fewer bits than the integral type used in C for things like buffer/string positions outside of the 29-bit integer range. How do you think Emacs managed 64-bit doubles "inside" of a 32-bit integral type used for representing Lisp cells? >> > If the variable that holds buffer positions needs to support 61-bit >> > offsets, it will have to be a 64-bit integral data type from the >> > get-go. >> >> I repeat: we are talking about a 32-bit binary where restricting buffer >> and string size to 32bit offsets would be reasonable and expected. > > You cannot have full 32-bit offsets without enlarging the width of a > Lisp integer. You most certainly can by transparent degradation to GMP numbers. That's exactly how GUILE does it. >> Choose a C type of your choosing for dealing with buffer offsets, >> create aliases for its conversions, and you are good to go. > > We _have_ chosen: it's a 64-bit 'long long'. What do you suggest to > choose instead? Any suggested type should be representable as an > Emacs integer. An "Emacs integer" is a Lisp data type. You are confusing this with the C type we use for Lisp cells, and with the C types we might use for buffer and/or string offsets. I can't believe we are having this conversation. Emacs integers so far are 29 bits, Emacs floats are 64 bits, Emacs cell types are 32 bits and I don't understand how one can imagine that they are somehow all the same. >> > And having 61-bit integers for integer arithmetics is also a >> > valuable feature. >> >> 61-bit is some arbitrary junk number. Transparently degrading from >> 29-bits to gmp numbers means that there are no arbitrary limits (or >> at least you are unlikely to hit them) and the performance for the >> vast majority of cases will be 29-bit performance. > > I don't understand how you intend to "transparently degrade" in the > implementation of '+', for example. If the numbers have different signs and are single-cell integers, the result fits. Otherwise you add them and if the result (after conversion to 29 bits) has a different sign than the starting numbers, you convert the result instead to a GMP number. > Are you going to test each argument for whether it fits into 32-bit > limits, 29-bit limits. I don't need to test the arguments since they will be single-cell integers only _when_ they fit. I only need to test the result. > and if so, invoke 32-bit arithmetics, else 64-bit arithmetics? If so, > I'm quite sure the test will steal cycles that will make this slower > than just always using 64-bit arithmetics. Disregarding the memory requirements and bandwidth for always using 64-bit. Why don't we use 256 bit for everything? It makes even more things work at the cost of eating even more memory and speed. One has to choose a sensible cutoff point for the default number representation, and whether one will admit more than that. A sensible cutoff point is what fits into a Lisp cell of natural processor size. GMP allows to admit lots more in the rare case where it is needed. This is what GUILE does and most Lisp implementations with "arbitrary precision" arithmetic do. > If you mean something else, can you show some C code that would > demonstrate your ideas? Any application using GUILE and its C API. Read the GUILE manual for all the details. This is not hypothetical, and as I already said, there is as far as I know a compile time option for SXEmacs at least and possibly also standard XEmacs to get this behavior for integers. This is not a pipe dream as you appear to insinuate. >> > So the EMACS_INT type will have to be able to support that. >> >> I don't see why when one can use GMP (which effectively uses the same >> kind arithmetic for 61-bit numbers as C does but does not stop there). > > Because calling a GMP function will most probably yield slower code > than if we let the compiler emit a few instructions required for > 64-bit arithmetics. GMP needs to be called only when leaving the range of "small integers" (which is all we even have right now). 64-bit arithmetic in your plan would be required for every single operation. Yes, when GMP kicks in, it will be slower than operations using exactly 64-bit (not more, not less). But it's the exception rather than the rule. So much the exception that we could entirely make do without it so far. It _will_ occur frequently when editing files larger than 1GB or so. But only in the _Lisp_ representations of those buffer positions. Everything implemented in C will use the integral data type we choose for that, throwing an error when it gets exceeded. And for a standard 32-bit compilation, 32-bit integers seem like a reasonable cutoff point: you'll not be able to load much more than 2G characters into a 32-bit address space anyway. Yes, not all of the possible offsets will be representable in one Lisp cell. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 14:03 ` David Kastrup @ 2015-10-16 16:01 ` Eli Zaretskii 2015-10-16 16:28 ` David Kastrup 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-10-16 16:01 UTC (permalink / raw) To: David Kastrup; +Cc: lekktu, eggert, emacs-devel > From: David Kastrup <dak@gnu.org> > Cc: eggert@cs.ucla.edu, lekktu@gmail.com, emacs-devel@gnu.org > Date: Fri, 16 Oct 2015 16:03:09 +0200 > > >> Isn't that also changing the size of a Lisp cell? And of integer > >> arithmetic? > > > > Part of it, yes. But since a Lisp cell can hold buffer or string > > position, what else can you expect? > > That buffer or string positions not representable in the 29 bits or so > available for integers in a Lisp cell are instead represented using a > gpm number for which there is a reference in the Lisp cell. But a GPM number is nothing more or less that some C data type. It's not some magic wand that can solve problems just by being there. > You are apparently unable to deal with the concept of a Lisp type being > represented by fewer bits than the integral type used in C for things > like buffer/string positions outside of the 29-bit integer range. Let's agree to keep such comments out of this discussion, OK? Otherwise, I will simply end it. > How do you think Emacs managed 64-bit doubles "inside" of a 32-bit > integral type used for representing Lisp cells? So you are suggesting to make a Lisp integer represented like a Lisp float, i.e. accessible via a pointer? But that in itself will slow down integer arithmetics, due to the need to dereference the pointer, won't it? > GMP needs to be called only when leaving the range of "small integers" > (which is all we even have right now). 64-bit arithmetic in your plan > would be required for every single operation. Yes, when GMP kicks in, > it will be slower than operations using exactly 64-bit (not more, not > less). But it's the exception rather than the rule. But there has to be a test for when the exception happens, and that test is going to exert its price on every operation, whether it succeeds or fails the test. I'm not at all sure it will be a net win. > So much the > exception that we could entirely make do without it so far. It _will_ > occur frequently when editing files larger than 1GB or so. But only in > the _Lisp_ representations of those buffer positions. Everything > implemented in C will use the integral data type we choose for that, > throwing an error when it gets exceeded. So you are suggesting to give up the transparent exposure of members of Lisp objects that are integers? > Yes, not all of the possible offsets will be representable in one > Lisp cell. So you are suggesting that a buffer position will not always be a simple number, but will sometimes be a cons cell? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 16:01 ` Eli Zaretskii @ 2015-10-16 16:28 ` David Kastrup 0 siblings, 0 replies; 765+ messages in thread From: David Kastrup @ 2015-10-16 16:28 UTC (permalink / raw) To: Eli Zaretskii; +Cc: lekktu, eggert, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: David Kastrup <dak@gnu.org> >> Cc: eggert@cs.ucla.edu, lekktu@gmail.com, emacs-devel@gnu.org >> Date: Fri, 16 Oct 2015 16:03:09 +0200 >> >> >> Isn't that also changing the size of a Lisp cell? And of integer >> >> arithmetic? >> > >> > Part of it, yes. But since a Lisp cell can hold buffer or string >> > position, what else can you expect? >> >> That buffer or string positions not representable in the 29 bits or so >> available for integers in a Lisp cell are instead represented using a >> gpm number for which there is a reference in the Lisp cell. > > But a GPM number is nothing more or less that some C data type. It's > not some magic wand that can solve problems just by being there. > >> How do you think Emacs managed 64-bit doubles "inside" of a 32-bit >> integral type used for representing Lisp cells? > > So you are suggesting to make a Lisp integer represented like a Lisp > float, i.e. accessible via a pointer? For values not fitting into 29 bits, yes. > But that in itself will slow down integer arithmetics, due to the need > to dereference the pointer, won't it? For values not fitting into 29 bits, yes. >> GMP needs to be called only when leaving the range of "small >> integers" (which is all we even have right now). 64-bit arithmetic >> in your plan would be required for every single operation. Yes, when >> GMP kicks in, it will be slower than operations using exactly 64-bit >> (not more, not less). But it's the exception rather than the rule. > > But there has to be a test for when the exception happens, and that > test is going to exert its price on every operation, whether it > succeeds or fails the test. I'm not at all sure it will be a net win. With regard to memory requirements and processing speed for values fitting easily into 32Bit (including booleans, indirect types, symbols, various other stuff), it will be a net win. Not everything in Lisp is an integer. >> So much the exception that we could entirely make do without it so >> far. It _will_ occur frequently when editing files larger than 1GB >> or so. But only in the _Lisp_ representations of those buffer >> positions. Everything implemented in C will use the integral data >> type we choose for that, throwing an error when it gets exceeded. > > So you are suggesting to give up the transparent exposure of members > of Lisp objects that are integers? I have no idea what you are talking about. Integers and Lisp cells are not the same. Treating them as the same is a bug. Just ask Stefan. So I have no idea what you call "transparent exposure" here. >> Yes, not all of the possible offsets will be representable in one >> Lisp cell. > > So you are suggesting that a buffer position will not always be a > simple number, but will sometimes be a cons cell? No. It will always be a Lisp integer, but Lisp integers will not always be stored in a single cell. But GMP does not store its numbers in cons cells. Really, I have no idea what your problem here is. Smooth degradation to fit rare large values compactly is not a particularly uncommon concept. Emacs uses it, for example, in UTF-8 representations of 8-bit encodings. It represents character codes 0-127 as-is, then switches to non-byte representation of 128-255. Why don't we use 32-bit characters from the get-go? Because they are rarely needed and we don't want to always pay the price in memory for the rarely needed cases. Doubling the size of Lisp cells does not just (roughly) double the size of all integers. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 8:18 ` David Kastrup 2015-10-16 8:49 ` Paul Eggert 2015-10-16 9:06 ` Eli Zaretskii @ 2015-10-16 15:53 ` Stephen J. Turnbull 2015-10-16 16:01 ` David Kastrup 2 siblings, 1 reply; 765+ messages in thread From: Stephen J. Turnbull @ 2015-10-16 15:53 UTC (permalink / raw) To: David Kastrup; +Cc: emacs-devel David Kastrup writes: > Instead of going to 64-bit unilaterally it would seem to make more > sense to me to degrade gracefully into gmp. GUILE does that, I > think that XEmacs or SXEmacs can do it, XEmacs can't handle greater than 1 GB buffers on a 32-bit machine. Yes, when bignums are enabled Lisp arithmetic will automatically overflow to bignums (and bigfloats), but internal accounting for text objects uses EMACS_INTs, not Lisp integers. At one time there were several users who preferred XEmacs to Emacs because they were routinely manipulating 512MB+ buffers and files. If you just want big Lisp integers, yes, bignums are nice. To be honest, I don't think it's a good idea to use bignums for internal indexes into text objects. 1 exabyte buffers should be enough to keep even the full archives of emacs-devel with room to spare for a while. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Making --with-wide-int the default 2015-10-16 15:53 ` Stephen J. Turnbull @ 2015-10-16 16:01 ` David Kastrup 0 siblings, 0 replies; 765+ messages in thread From: David Kastrup @ 2015-10-16 16:01 UTC (permalink / raw) To: Stephen J. Turnbull; +Cc: emacs-devel "Stephen J. Turnbull" <stephen@xemacs.org> writes: > David Kastrup writes: > > > Instead of going to 64-bit unilaterally it would seem to make more > > sense to me to degrade gracefully into gmp. GUILE does that, I > > think that XEmacs or SXEmacs can do it, > > XEmacs can't handle greater than 1 GB buffers on a 32-bit machine. > Yes, when bignums are enabled Lisp arithmetic will automatically > overflow to bignums (and bigfloats), but internal accounting for text > objects uses EMACS_INTs, not Lisp integers. At one time there were > several users who preferred XEmacs to Emacs because they were > routinely manipulating 512MB+ buffers and files. > > If you just want big Lisp integers, yes, bignums are nice. > > To be honest, I don't think it's a good idea to use bignums for > internal indexes into text objects. 1 exabyte buffers should be > enough to keep even the full archives of emacs-devel with room to > spare for a while. If a particular application warrants a particular C integral type, you can always use the appropriate conversion routine for extracting it and it will throw an error when the result does not fit the type. That's the way one works with GUILE, and it's perfectly usable. When stuff blows up, it does so with an error message and at the limits of the values that the C code can deal with rather than something like a 30-bit integer. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 10:44 ` Aurélien Aptel 2015-10-15 15:41 ` Eli Zaretskii @ 2015-10-15 23:11 ` Philipp Stephani 1 sibling, 0 replies; 765+ messages in thread From: Philipp Stephani @ 2015-10-15 23:11 UTC (permalink / raw) To: Aurélien Aptel Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 1382 bytes --] Aurélien Aptel <aurelien.aptel+emacs@gmail.com> schrieb am Do., 15. Okt. 2015 um 12:44 Uhr: > On Thu, Oct 15, 2015 at 2:25 AM, Philipp Stephani <p.stephani2@gmail.com> > wrote: > > Agreed. I've implemented Daniel's suggestion on the tls-error branch, it > > seems to work fine (but note that environments are now no longer global, > so > > storing away emacs_values without global references now will lead to > > undefined behavior). > > Yeah I just realized that. The nice thing with just casting is its the > same memory object and the stack-scanning GC just works. Having the GC > is nice... > Until you change the GC algorithm to a precise GC or reference counting and cause all modules to crash, leak memory, or worse. This is exactly the kind of dependency on implementation details that we want to avoid with a clean module interface. > Again, IIUC, the only problem is on 32bit with wide-int, which is off > by default. > > Even if sizeof(Lisp_Object) == sizeof(void*), you still need the guarantee that (Lisp_Object)((void*)0) is an invalid Lisp object. > > Let's see what will get accepted upstream. > > That's sneaky... but this is how the free software world works I guess... > I don't think it's sneaky. The opinions of everyone are known and have been discussed ad nauseam in public. Either it gets accepted or it doesn't. [-- Attachment #2: Type: text/html, Size: 2088 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 0:25 ` Philipp Stephani 2015-10-15 10:44 ` Aurélien Aptel @ 2015-10-15 23:15 ` Philipp Stephani 2015-10-19 22:38 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-10-15 23:15 UTC (permalink / raw) To: Aurélien Aptel Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 256 bytes --] I just realized that we need (at least) one more public environment function, either "null" or "eq". Otherwise conditions cannot be written in module code. I'd vote for bool is_not_null, it seems to be the most basic one, and doesn't invert the condition. [-- Attachment #2: Type: text/html, Size: 327 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 23:15 ` Philipp Stephani @ 2015-10-19 22:38 ` Philipp Stephani 2015-10-20 1:58 ` Daniel Colascione 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-10-19 22:38 UTC (permalink / raw) To: Aurélien Aptel Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 1550 bytes --] Philipp Stephani <p.stephani2@gmail.com> schrieb am Fr., 16. Okt. 2015 um 01:15 Uhr: > I just realized that we need (at least) one more public environment > function, either "null" or "eq". Otherwise conditions cannot be written in > module code. > I'd vote for bool is_not_null, it seems to be the most basic one, and > doesn't invert the condition. > There are still a few open questions: 1. How to represent throw/catch. Currently it's not possible to throw from modules, but that should change because otherwise modules can't be transparent. For example, the following couldn't work: emacs_value top_level = env->intern(env, "top-level"); if (!top_level) return NULL; return env->funcall(env, top_level, 0, NULL); because `top-level' uses `throw'. There are several ways to represent `throw'. My suggestion would still be to use an enum instead of the bool value for get_error and check_error. Otherwise the fact that a `throw' has happened has to be encoded somehow in the error symbol, which to me seems rather hackish and not future-proof. (What happens if Emacs would ever allow to signal a list?) 2. Whether type_of should return an enum or a symbol. I'd vote for the symbol, as in Daniel's original design. 3. Can runtime->get_environment ever fail? 4. Some of the function (free_global_ref, the int/float extractors) don't return emacs_value and have no clear way to signal an error. For these function the caller always has to use check_error/get_error. Is that good enough? [-- Attachment #2: Type: text/html, Size: 1936 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-19 22:38 ` Philipp Stephani @ 2015-10-20 1:58 ` Daniel Colascione 2015-10-20 3:05 ` Tom Tromey 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-10-20 1:58 UTC (permalink / raw) To: Philipp Stephani, Aurélien Aptel Cc: Eli Zaretskii, Stephen Leake, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 2532 bytes --] On 10/19/2015 03:38 PM, Philipp Stephani wrote: > Philipp Stephani <p.stephani2@gmail.com <mailto:p.stephani2@gmail.com>> > schrieb am Fr., 16. Okt. 2015 um 01:15 Uhr: > > I just realized that we need (at least) one more public environment > function, either "null" or "eq". Otherwise conditions cannot be > written in module code. > I'd vote for bool is_not_null, it seems to be the most basic one, > and doesn't invert the condition. Yes, we do. I'd prefer eq, since the definition will never change, and having a nice convenient way to access eq is useful in more situations than a specialized test for eq nil. > There are still a few open questions: > > 1. How to represent throw/catch. Currently it's not possible to throw > from modules, but that should change because otherwise modules can't > be transparent. For example, the following couldn't work: > > emacs_value top_level = env->intern(env, "top-level"); > if (!top_level) return NULL; > return env->funcall(env, top_level, 0, NULL); > > because `top-level' uses `throw'. > There are several ways to represent `throw'. My suggestion would > still be to use an enum instead of the bool value for get_error and > check_error. Otherwise the fact that a `throw' has happened has to > be encoded somehow in the error symbol, which to me seems rather > hackish and not future-proof. (What happens if Emacs would ever > allow to signal a list?) An enum to indicate the current thread's non-local error propagation state is probably fine. > 2. Whether type_of should return an enum or a symbol. I'd vote for the > symbol, as in Daniel's original design. A symbol means that we can define as many types as we want. > 3. Can runtime->get_environment ever fail? Maybe we should actually get rid of get_environment and rely entirely on passed-in environment objects. It simplifies the API and avoids definitional problems. > 4. Some of the function (free_global_ref, the int/float extractors) > don't return emacs_value and have no clear way to signal an error. > For these function the caller always has to use > check_error/get_error. Is that good enough? free_global_ref, like all resource-releasing functions, should be infallible. For other functions, asking users to check the error state after a call is fine, although we should also return reasonable dummy values (0 and NaN, probably) as well in case they don't. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-20 1:58 ` Daniel Colascione @ 2015-10-20 3:05 ` Tom Tromey 2015-10-20 3:13 ` Daniel Colascione 0 siblings, 1 reply; 765+ messages in thread From: Tom Tromey @ 2015-10-20 3:05 UTC (permalink / raw) To: Daniel Colascione Cc: Aurélien Aptel, Philipp Stephani, Stephen Leake, Eli Zaretskii, Emacs development discussions Daniel> Yes, we do. I'd prefer eq, since the definition will never change, and Daniel> having a nice convenient way to access eq is useful in more situations Daniel> than a specialized test for eq nil. Both are useful and it is cheap to provide a method, so why not have both eq and nilp? Daniel> Maybe we should actually get rid of get_environment and rely entirely on Daniel> passed-in environment objects. It simplifies the API and avoids Daniel> definitional problems. Yeah, I brought this up earlier and I still don't understand the reason for the runtime/environment split. >> 4. Some of the function (free_global_ref, the int/float extractors) >> don't return emacs_value and have no clear way to signal an error. >> For these function the caller always has to use >> check_error/get_error. Is that good enough? Daniel> free_global_ref, like all resource-releasing functions, should be Daniel> infallible. For other functions, asking users to check the error state Daniel> after a call is fine, although we should also return reasonable dummy Daniel> values (0 and NaN, probably) as well in case they don't. It might be handy if there was a special emacs_value meaning that an error occurred. Tom ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-20 3:05 ` Tom Tromey @ 2015-10-20 3:13 ` Daniel Colascione 2015-10-20 3:32 ` Tom Tromey 2015-10-20 15:48 ` Stephen Leake 0 siblings, 2 replies; 765+ messages in thread From: Daniel Colascione @ 2015-10-20 3:13 UTC (permalink / raw) To: Tom Tromey Cc: Aurélien Aptel, Philipp Stephani, Stephen Leake, Eli Zaretskii, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 2176 bytes --] On 10/19/2015 08:05 PM, Tom Tromey wrote: > Daniel> Yes, we do. I'd prefer eq, since the definition will never change, and > Daniel> having a nice convenient way to access eq is useful in more situations > Daniel> than a specialized test for eq nil. > > Both are useful and it is cheap to provide a method, so why not have > both eq and nilp? I have no objection to including both. > Daniel> Maybe we should actually get rid of get_environment and rely entirely on > Daniel> passed-in environment objects. It simplifies the API and avoids > Daniel> definitional problems. > > Yeah, I brought this up earlier and I still don't understand the reason > for the runtime/environment split. A runtime describes Emacs as a whole. It lives forever and has no thread affinity. An environment represents a specific stack activation of an Emacs module function. It has thread affinity. Because environments have thread affinity, we can very cheaply store local references, error context, and whatever else we want in them. We could probably get away with only defining environments, but then we'd have no way to allow routines to call Emacs routines at any time. (Useful future runtime routines might be "attach this thread to the Lisp engine", "send QUIT to the main thread", "abort spectacularly", "get Emacs version", and so on.) >>> 4. Some of the function (free_global_ref, the int/float extractors) >>> don't return emacs_value and have no clear way to signal an error. >>> For these function the caller always has to use >>> check_error/get_error. Is that good enough? > > Daniel> free_global_ref, like all resource-releasing functions, should be > Daniel> infallible. For other functions, asking users to check the error state > Daniel> after a call is fine, although we should also return reasonable dummy > Daniel> values (0 and NaN, probably) as well in case they don't. > > It might be handy if there was a special emacs_value meaning that an > error occurred. We have a perfectly good sentinel: NULL. NULL will never be a valid local or global reference, so it's safe to use it to indicate that something went wrong. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-20 3:13 ` Daniel Colascione @ 2015-10-20 3:32 ` Tom Tromey 2015-10-20 3:38 ` Daniel Colascione 2015-10-20 15:48 ` Stephen Leake 1 sibling, 1 reply; 765+ messages in thread From: Tom Tromey @ 2015-10-20 3:32 UTC (permalink / raw) To: Daniel Colascione Cc: Emacs development discussions, Philipp Stephani, Aurélien Aptel, Eli Zaretskii, Tom Tromey, Stephen Leake Daniel> A runtime describes Emacs as a whole. It lives forever and has Daniel> no thread affinity. Thanks. Daniel> We have a perfectly good sentinel: NULL. NULL will never be a valid Daniel> local or global reference, so it's safe to use it to indicate that Daniel> something went wrong. Ok, I see, it really is JNI. I was confused because the module API doesn't implement this. This design seems a bit odd for Emacs in that "immediate" things like ints will still have to be wrapped in references. Tom ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-20 3:32 ` Tom Tromey @ 2015-10-20 3:38 ` Daniel Colascione 0 siblings, 0 replies; 765+ messages in thread From: Daniel Colascione @ 2015-10-20 3:38 UTC (permalink / raw) To: Tom Tromey Cc: Aurélien Aptel, Philipp Stephani, Stephen Leake, Eli Zaretskii, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 1330 bytes --] On 10/19/2015 08:32 PM, Tom Tromey wrote: > Daniel> A runtime describes Emacs as a whole. It lives forever and has > Daniel> no thread affinity. > > Thanks. > > Daniel> We have a perfectly good sentinel: NULL. NULL will never be a valid > Daniel> local or global reference, so it's safe to use it to indicate that > Daniel> something went wrong. > > Ok, I see, it really is JNI. I was confused because the module API > doesn't implement this. Sure, although I'd like it to. If we use the currently-implemented approach, it's not a disaster. It'd just be a shame to have to cart around long long values on 32-bit platforms even when Emacs is compiled with plain 32-bit values. > This design seems a bit odd for Emacs in that "immediate" things like > ints will still have to be wrapped in references. Right, because we're not strongly typed like Java. The references are cheap enough though, and there's no awkardness around pointer width or type tagging. Once we get a numeric tower, it'll be possible to store a full 32 bits in an emacs_value without having to be aware that there's an indirection. This approach also completely insulates us from GC changes: we could even implement a compacting collector without modules being aware of it. FWIW, it's not just JNI. V8 works the same way. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-20 3:13 ` Daniel Colascione 2015-10-20 3:32 ` Tom Tromey @ 2015-10-20 15:48 ` Stephen Leake 2015-10-20 18:52 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Stephen Leake @ 2015-10-20 15:48 UTC (permalink / raw) To: Daniel Colascione Cc: Aurélien Aptel, Philipp Stephani, Tom Tromey, Eli Zaretskii, Emacs development discussions Daniel Colascione <dancol@dancol.org> writes: > A runtime describes Emacs as a whole. It lives forever and has no thread > affinity. An environment represents a specific stack activation of an > Emacs module function. It has thread affinity. Because environments have > thread affinity, we can very cheaply store local references, error > context, and whatever else we want in them. Please add this to comments in the API, so we don't forget. or add a module_design.texi, for this and similar design info. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-20 15:48 ` Stephen Leake @ 2015-10-20 18:52 ` Philipp Stephani 2015-10-22 12:57 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-10-20 18:52 UTC (permalink / raw) To: Stephen Leake, Daniel Colascione Cc: Aurélien Aptel, Eli Zaretskii, Tom Tromey, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 822 bytes --] Stephen Leake <stephen_leake@stephe-leake.org> schrieb am Di., 20. Okt. 2015 um 17:48 Uhr: > Daniel Colascione <dancol@dancol.org> writes: > > > A runtime describes Emacs as a whole. It lives forever and has no thread > > affinity. An environment represents a specific stack activation of an > > Emacs module function. It has thread affinity. Because environments have > > thread affinity, we can very cheaply store local references, error > > context, and whatever else we want in them. > > Please add this to comments in the API, so we don't forget. > > Or implement it incorrectly. For example, the runtime object in my pull request is local to the init function. If the runtime object is static, does its get_environment function always return the same environment? In other words, is that environment also static? [-- Attachment #2: Type: text/html, Size: 1240 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-20 18:52 ` Philipp Stephani @ 2015-10-22 12:57 ` Aurélien Aptel 2015-10-22 17:56 ` Aurélien Aptel 2015-10-22 22:49 ` Philipp Stephani 0 siblings, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-10-22 12:57 UTC (permalink / raw) To: Philipp Stephani Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions, Tom Tromey I've added user-pointer objects. Some feedback I had off-list: * add functions to the API for fast vector access as it currently requires too much boxing/unboxing of integers for doing length/indexing stuff. * expose fast read-only string access (not sure how do-able this is considering the encoding problem) * consider NULL as a no-op finalizer. Philip, you obviously have more experienced in this memory handling stuff so I'm going to trust you and merge what you did (but there are merge conflicts on the last pull requests atm, havent looked into it). Thanks again for your work :) This module API is slowly but surely materializing. The interface is lot more clean and user-friendly than my initial plan. I hope we can have good performances where it matters to make it really useful :) ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-22 12:57 ` Aurélien Aptel @ 2015-10-22 17:56 ` Aurélien Aptel 2015-10-22 18:03 ` Eli Zaretskii 2015-10-22 22:49 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-10-22 17:56 UTC (permalink / raw) To: Philipp Stephani Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions, Tom Tromey I've finally compiled emacs on a Windows VM using msys2 & mingw-w64! After doing basically nothing (adding the proper $opsys check and setting HAVE_MODULES to "yes" in the configure script...) I was able to build and run successfully all test modules on Windows. Note that the modules makefile still hardcode the .so suffix for shared libraries (even though gcc ouputs regular PE DLLs) and loading them as-is works anyway. Neat. I'll change that, eventually. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-22 17:56 ` Aurélien Aptel @ 2015-10-22 18:03 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-10-22 18:03 UTC (permalink / raw) To: Aurélien Aptel; +Cc: p.stephani2, dancol, stephen_leake, emacs-devel, tom > Date: Thu, 22 Oct 2015 19:56:00 +0200 > From: Aurélien Aptel <aurelien.aptel+emacs@gmail.com> > Cc: Stephen Leake <stephen_leake@stephe-leake.org>, Daniel Colascione <dancol@dancol.org>, > Tom Tromey <tom@tromey.com>, Eli Zaretskii <eliz@gnu.org>, > Emacs development discussions <emacs-devel@gnu.org> > > I've finally compiled emacs on a Windows VM using msys2 & mingw-w64! > > After doing basically nothing (adding the proper $opsys check and > setting HAVE_MODULES to "yes" in the configure script...) I was able > to build and run successfully all test modules on Windows. Note that > the modules makefile still hardcode the .so suffix for shared > libraries (even though gcc ouputs regular PE DLLs) and loading them > as-is works anyway. Neat. I'll change that, eventually. Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-22 12:57 ` Aurélien Aptel 2015-10-22 17:56 ` Aurélien Aptel @ 2015-10-22 22:49 ` Philipp Stephani 2015-10-22 22:52 ` Daniel Colascione ` (2 more replies) 1 sibling, 3 replies; 765+ messages in thread From: Philipp Stephani @ 2015-10-22 22:49 UTC (permalink / raw) To: Aurélien Aptel Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions, Tom Tromey [-- Attachment #1: Type: text/plain, Size: 1709 bytes --] Aurélien Aptel <aurelien.aptel+emacs@gmail.com> schrieb am Do., 22. Okt. 2015 um 14:57 Uhr: > I've added user-pointer objects. Some feedback I had off-list: > > * add functions to the API for fast vector access as it currently > requires too much boxing/unboxing of integers for doing > length/indexing stuff. > This would make sense. Same with things like car and cdr etc. However, we should be careful not to overload the module interface. It might make sense to do some basic measurements using a real-life example and optimize only the hotspots. > * expose fast read-only string access (not sure how do-able this is > considering the encoding problem) > If the internal Emacs encoding is not defined, then we probably shouldn't expose it to modules. What should modules do with such string access? They could only treat the contents as opaque byte arrays. > * consider NULL as a no-op finalizer. > > Philip, you obviously have more experienced in this memory handling > stuff so I'm going to trust you and merge what you did (but there are > merge conflicts on the last pull requests atm, havent looked into it). > Thanks again for your work :) > You're welcome, thanks for implementing the module stuff in the first place! I'm not really experienced either, I've simply implemented what Daniel has proposed (a simple list of blocks). I've merged your branch and pushed to my fork, so you should be able to merge one of the PRs now. > > This module API is slowly but surely materializing. The interface is > lot more clean and user-friendly than my initial plan. I hope we can > have good performances where it matters to make it really useful :) > [-- Attachment #2: Type: text/html, Size: 2469 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-22 22:49 ` Philipp Stephani @ 2015-10-22 22:52 ` Daniel Colascione 2015-10-23 7:05 ` Eli Zaretskii 2015-10-23 7:00 ` Eli Zaretskii 2015-10-25 16:26 ` Aurélien Aptel 2 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-10-22 22:52 UTC (permalink / raw) To: Philipp Stephani, Aurélien Aptel Cc: Eli Zaretskii, Tom Tromey, Stephen Leake, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 1257 bytes --] On 10/22/2015 03:49 PM, Philipp Stephani wrote: > > > Aurélien Aptel <aurelien.aptel+emacs@gmail.com > <mailto:aurelien.aptel%2Bemacs@gmail.com>> schrieb am Do., 22. Okt. 2015 > um 14:57 Uhr: > > I've added user-pointer objects. Some feedback I had off-list: > > * add functions to the API for fast vector access as it currently > requires too much boxing/unboxing of integers for doing > length/indexing stuff. > > > This would make sense. Same with things like car and cdr etc. > However, we should be careful not to overload the module interface. It > might make sense to do some basic measurements using a real-life example > and optimize only the hotspots. Agreed. > > > * expose fast read-only string access (not sure how do-able this is > considering the encoding problem) > > > If the internal Emacs encoding is not defined, then we probably > shouldn't expose it to modules. What should modules do with such string > access? They could only treat the contents as opaque byte arrays. Agreed, although there may be a reasonable case for an API that provides direct access to strings that happen to be ASCII (or UTF-8) and that runs a conversion otherwise, all transparently. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-22 22:52 ` Daniel Colascione @ 2015-10-23 7:05 ` Eli Zaretskii 2015-10-23 7:17 ` Daniel Colascione 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-10-23 7:05 UTC (permalink / raw) To: Daniel Colascione Cc: aurelien.aptel+emacs, p.stephani2, tom, stephen_leake, emacs-devel > Cc: Stephen Leake <stephen_leake@stephe-leake.org>, > Tom Tromey <tom@tromey.com>, Eli Zaretskii <eliz@gnu.org>, > Emacs development discussions <emacs-devel@gnu.org> > From: Daniel Colascione <dancol@dancol.org> > Date: Thu, 22 Oct 2015 15:52:58 -0700 > > > * expose fast read-only string access (not sure how do-able this is > > considering the encoding problem) > > > > > > If the internal Emacs encoding is not defined, then we probably > > shouldn't expose it to modules. What should modules do with such string > > access? They could only treat the contents as opaque byte arrays. > > Agreed, although there may be a reasonable case for an API that provides > direct access to strings that happen to be ASCII (or UTF-8) and that > runs a conversion otherwise, all transparently. Not sure what you mean here. First, the internal representation is a superset of UTF-8, so if we can provide direct access to UTF-8, why not let modules access the internal representation? Second, if by "UTF-8" you mean a unibyte string encoded in strict UTF-8, then why limit that to UTF-8? Standard C runtime can handle many different encodings, including multibyte ones, it is not limited to UTF-8 (although UTF-8 is easier for certain tasks). Therefore, I think access to unibyte strings (a.k.a. "byte streams") should not be limited at all, and letting modules access multibyte strings in their internal representation would be a significant bonus we shouldn't easily give up on. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-23 7:05 ` Eli Zaretskii @ 2015-10-23 7:17 ` Daniel Colascione 0 siblings, 0 replies; 765+ messages in thread From: Daniel Colascione @ 2015-10-23 7:17 UTC (permalink / raw) To: Eli Zaretskii Cc: aurelien.aptel+emacs, p.stephani2, tom, stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1225 bytes --] On 10/23/2015 12:05 AM, Eli Zaretskii wrote: >> Cc: Stephen Leake <stephen_leake@stephe-leake.org>, >> Tom Tromey <tom@tromey.com>, Eli Zaretskii <eliz@gnu.org>, >> Emacs development discussions <emacs-devel@gnu.org> >> From: Daniel Colascione <dancol@dancol.org> >> Date: Thu, 22 Oct 2015 15:52:58 -0700 >> >>> * expose fast read-only string access (not sure how do-able this is >>> considering the encoding problem) >>> >>> >>> If the internal Emacs encoding is not defined, then we probably >>> shouldn't expose it to modules. What should modules do with such string >>> access? They could only treat the contents as opaque byte arrays. >> >> Agreed, although there may be a reasonable case for an API that provides >> direct access to strings that happen to be ASCII (or UTF-8) and that >> runs a conversion otherwise, all transparently. > > Not sure what you mean here. First, the internal representation is a > superset of UTF-8, so if we can provide direct access to UTF-8, why > not let modules access the internal representation? You're right. There are few downsides to providing direct access provided we document that strings are usually, but not always, strict UTF-8. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-22 22:49 ` Philipp Stephani 2015-10-22 22:52 ` Daniel Colascione @ 2015-10-23 7:00 ` Eli Zaretskii 2015-10-25 16:26 ` Aurélien Aptel 2 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-10-23 7:00 UTC (permalink / raw) To: Philipp Stephani Cc: aurelien.aptel+emacs, emacs-devel, dancol, stephen_leake, tom > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Thu, 22 Oct 2015 22:49:01 +0000 > Cc: Stephen Leake <stephen_leake@stephe-leake.org>, Daniel Colascione <dancol@dancol.org>, > Tom Tromey <tom@tromey.com>, Eli Zaretskii <eliz@gnu.org>, > Emacs development discussions <emacs-devel@gnu.org> > > * expose fast read-only string access (not sure how do-able this is > considering the encoding problem) > > If the internal Emacs encoding is not defined, then we probably shouldn't > expose it to modules. It is well defined. > What should modules do with such string access? They could only > treat the contents as opaque byte arrays. That'd mean high-performance string processing in modules will be impossible, because you'd need either to use Lisp interfaces (and create a Lisp string for them each time you call them), or encode/decode each string before using it with libc functions. That'd be a pity, I think. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-22 22:49 ` Philipp Stephani 2015-10-22 22:52 ` Daniel Colascione 2015-10-23 7:00 ` Eli Zaretskii @ 2015-10-25 16:26 ` Aurélien Aptel 2015-10-25 16:31 ` Philipp Stephani 2 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-10-25 16:26 UTC (permalink / raw) To: Philipp Stephani Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions, Tom Tromey Philip, I've tried to merge you latest PR but I have a problem with module compiled with -fsanitize-address. This compiles the module with ASan aka AddressSanitizer on GCC. You've enable it to debug memory problems I guess and it looks useful but I cannot load them. [*] ./modt-error: running make gcc -fsanitize=address -ggdb3 -Wall -I../../src -fPIC -c modt-error.c gcc -shared -fsanitize=address -o modt-error.so modt-error.o ../../lib-src/make-docfile modt-error.c > modt-error.doc rm modt-error.o [*] ./modt-error: running test ../src/emacs -batch -L . -l ert -l ./modt-error/test.el -f ert-run-tests-batch-and-exit ==24402==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD. [E] ./modt-error: test failed I'm sure I'm missing something obvious... ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-25 16:26 ` Aurélien Aptel @ 2015-10-25 16:31 ` Philipp Stephani 2015-10-25 18:45 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-10-25 16:31 UTC (permalink / raw) To: Aurélien Aptel Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions, Tom Tromey [-- Attachment #1: Type: text/plain, Size: 1168 bytes --] Aurélien Aptel <aurelien.aptel+emacs@gmail.com> schrieb am So., 25. Okt. 2015 um 17:26 Uhr: > Philip, I've tried to merge you latest PR but I have a problem with > module compiled with -fsanitize-address. This compiles the module with > ASan aka AddressSanitizer on GCC. You've enable it to debug memory > problems I guess and it looks useful but I cannot load them. > > [*] ./modt-error: running make > gcc -fsanitize=address -ggdb3 -Wall -I../../src -fPIC -c modt-error.c > gcc -shared -fsanitize=address -o modt-error.so modt-error.o > ../../lib-src/make-docfile modt-error.c > modt-error.doc > rm modt-error.o > [*] ./modt-error: running test > ../src/emacs -batch -L . -l ert -l ./modt-error/test.el -f > ert-run-tests-batch-and-exit > ==24402==ASan runtime does not come first in initial library list; you > should either link runtime to your application or manually preload it > with LD_PRELOAD. > [E] ./modt-error: test failed > > I'm sure I'm missing something obvious... > I mainly use Clang, which is almost, but not entirely compatible with GCC. If the flag causes problems for you, just drop it, of course it's not required. [-- Attachment #2: Type: text/html, Size: 1506 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-25 16:31 ` Philipp Stephani @ 2015-10-25 18:45 ` Aurélien Aptel 2015-10-25 20:13 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-10-25 18:45 UTC (permalink / raw) To: Philipp Stephani Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions, Tom Tromey On Sun, Oct 25, 2015 at 5:31 PM, Philipp Stephani <p.stephani2@gmail.com> wrote: > I mainly use Clang, which is almost, but not entirely compatible with GCC. > If the flag causes problems for you, just drop it, of course it's not > required. Sure, but it looks useful so I'd like to make it work. In any case I've merged you PR and I've finished the `load' integration, which makes `require' works now. `Fload' does a lot of stuff and I'm short-circuiting a lot of it for modules. I would like some review on this [1] specifically src/lread.c changes. Do we need to do things before the function returns? I'm guessing we should close the fd returned by `openp' but if you grep for openp usage in the emacs codebase you'll notice some occurence where they don't even store the fd... https://github.com/aaptel/emacs-dynamic-module/commit/dc5cc38a50ea31b0d64c6664352c3bce88121411 ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-25 18:45 ` Aurélien Aptel @ 2015-10-25 20:13 ` Philipp Stephani 2015-10-25 20:40 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-10-25 20:13 UTC (permalink / raw) To: Aurélien Aptel Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions, Tom Tromey [-- Attachment #1: Type: text/plain, Size: 668 bytes --] Aurélien Aptel <aurelien.aptel+emacs@gmail.com> schrieb am So., 25. Okt. 2015 um 19:45 Uhr: > On Sun, Oct 25, 2015 at 5:31 PM, Philipp Stephani <p.stephani2@gmail.com> > wrote: > > I mainly use Clang, which is almost, but not entirely compatible with > GCC. > > If the flag causes problems for you, just drop it, of course it's not > > required. > > Sure, but it looks useful so I'd like to make it work. > I haven't investigated in detail what the problem is, but since newer GCCs support ASan, that should be doable. > > In any case I've merged you PR and I've finished the `load' > integration, which makes `require' works now. > Cool! [-- Attachment #2: Type: text/html, Size: 1201 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-25 20:13 ` Philipp Stephani @ 2015-10-25 20:40 ` Philipp Stephani 2015-10-25 20:55 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-10-25 20:40 UTC (permalink / raw) To: Aurélien Aptel Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions, Tom Tromey [-- Attachment #1: Type: text/plain, Size: 338 bytes --] One more thing: I'd suggest to unintern module-call and module-refs-hash, like we do with internal-interpreter-environment. They are implementation details that users can't meaningfully work with; in the case of module-call, users have no way to pass the needed environment pointer, and modifying module-refs-hash would be quite harmful. [-- Attachment #2: Type: text/html, Size: 368 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-25 20:40 ` Philipp Stephani @ 2015-10-25 20:55 ` Aurélien Aptel 2015-10-28 13:47 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-10-25 20:55 UTC (permalink / raw) To: Philipp Stephani Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions, Tom Tromey On Sun, Oct 25, 2015 at 9:40 PM, Philipp Stephani <p.stephani2@gmail.com> wrote: > One more thing: I'd suggest to unintern module-call and module-refs-hash, > like we do with internal-interpreter-environment. They are implementation > details that users can't meaningfully work with; in the case of module-call, > users have no way to pass the needed environment pointer, and modifying > module-refs-hash would be quite harmful. Good idea. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-25 20:55 ` Aurélien Aptel @ 2015-10-28 13:47 ` Aurélien Aptel 2015-11-06 15:52 ` Ted Zlatanov 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-10-28 13:47 UTC (permalink / raw) To: Philipp Stephani Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions, Tom Tromey I was thinking of doing a small talk on Emacs module support at FOSDEM in january. I hope by then we'll be close to done... *cross body appendices* ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-28 13:47 ` Aurélien Aptel @ 2015-11-06 15:52 ` Ted Zlatanov 2015-11-06 15:55 ` Eli Zaretskii 2015-11-06 21:52 ` Dynamic loading progress John Wiegley 0 siblings, 2 replies; 765+ messages in thread From: Ted Zlatanov @ 2015-11-06 15:52 UTC (permalink / raw) To: emacs-devel On Wed, 28 Oct 2015 14:47:42 +0100 Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: AA> I was thinking of doing a small talk on Emacs module support at FOSDEM AA> in january. I hope by then we'll be close to done... *cross body AA> appendices* I've tried to review the discussion so far and believe the code is "functional enough." I think we got agreement from Stefan (probably John too) to exempt dynamic modules from the feature freeze. If you agree, can you please push your branch into Emacs but turn tests off, so failures don't break the build? Or maybe mark them as soft failures, if that's possible. I am concerned that otherwise we'll make it harder and harder to accept the work for the upcoming release, and that would delay dynamic modules further. Developing in a feature branch is good up to a point, but now it's become an impediment because your work is not visible to a wider audience. I hope we all agree on this. I can push it if you don't have commit access; just let me know here or off-list when it's ready. The commit message formatting may need adjusting and we may want to squash into just a few commits, but these are minor details. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-06 15:52 ` Ted Zlatanov @ 2015-11-06 15:55 ` Eli Zaretskii 2015-11-06 16:22 ` Ted Zlatanov 2015-11-07 1:53 ` Feature freezes and Emacs 25 (was: Dynamic loading progress) John Wiegley 2015-11-06 21:52 ` Dynamic loading progress John Wiegley 1 sibling, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-06 15:55 UTC (permalink / raw) To: emacs-devel; +Cc: emacs-devel > From: Ted Zlatanov <tzz@lifelogs.com> > Date: Fri, 06 Nov 2015 10:52:04 -0500 > > I think we got agreement from Stefan (probably John too) to exempt > dynamic modules from the feature freeze. There's no feature freeze yet. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-06 15:55 ` Eli Zaretskii @ 2015-11-06 16:22 ` Ted Zlatanov 2015-11-07 1:53 ` Feature freezes and Emacs 25 (was: Dynamic loading progress) John Wiegley 1 sibling, 0 replies; 765+ messages in thread From: Ted Zlatanov @ 2015-11-06 16:22 UTC (permalink / raw) To: emacs-devel On Fri, 06 Nov 2015 17:55:22 +0200 Eli Zaretskii <eliz@gnu.org> wrote: >> From: Ted Zlatanov <tzz@lifelogs.com> >> Date: Fri, 06 Nov 2015 10:52:04 -0500 >> >> I think we got agreement from Stefan (probably John too) to exempt >> dynamic modules from the feature freeze. EZ> There's no feature freeze yet. I could swear I saw a message about it. Well, it's good to know, but the rest of my message still applies :) Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Feature freezes and Emacs 25 (was: Dynamic loading progress) 2015-11-06 15:55 ` Eli Zaretskii 2015-11-06 16:22 ` Ted Zlatanov @ 2015-11-07 1:53 ` John Wiegley 2015-11-07 8:32 ` Feature freezes and Emacs 25 David Kastrup ` (3 more replies) 1 sibling, 4 replies; 765+ messages in thread From: John Wiegley @ 2015-11-07 1:53 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel Since Emacs 25 is not yet released, the transfer of maintainership comes at a slightly awkward time. I haven't fully caught my breath yet, but don't want to impede Stefan's legacy from getting out the door. Let us officially freeze in one weeks, next Friday, Nov 13 at 11:59 PM UTC, so that any ready, last minute features can get in before 25.1 is closed. Then we'll take a pause and review whether anything should be allowed after the freeze. Once we're comfortable with the bug situation, we release. I'd like to take a somewhat generous period for bug fixes, with feature work happening in the meanwhile on topic branches. All severe bugs should either be closed, or consciously deferred, before letting 25 out the door. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-07 1:53 ` Feature freezes and Emacs 25 (was: Dynamic loading progress) John Wiegley @ 2015-11-07 8:32 ` David Kastrup 2015-11-07 8:46 ` Eli Zaretskii 2015-11-07 8:33 ` Feature freezes and Emacs 25 (was: Dynamic loading progress) Eli Zaretskii ` (2 subsequent siblings) 3 siblings, 1 reply; 765+ messages in thread From: David Kastrup @ 2015-11-07 8:32 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel John Wiegley <jwiegley@gmail.com> writes: > Since Emacs 25 is not yet released, the transfer of maintainership comes at a > slightly awkward time. I haven't fully caught my breath yet, but don't want to > impede Stefan's legacy from getting out the door. > > Let us officially freeze in one weeks, next Friday, Nov 13 at 11:59 PM > UTC, so that any ready, last minute features can get in before 25.1 is > closed. That sounds like a free-for-all. With the development cycles of Emacs, rushing in last-minute features might come at costs of half a year. I'd rather suggest putting down a "soft freeze" right now where anything significantly featuresome requires list/maintainer approval. In essence, this is vaguely the state Stefan handed over: I considered this somewhat fuzzily the prevailing mood to be picked up from discussions on the list. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-07 8:32 ` Feature freezes and Emacs 25 David Kastrup @ 2015-11-07 8:46 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-07 8:46 UTC (permalink / raw) To: David Kastrup; +Cc: emacs-devel > From: David Kastrup <dak@gnu.org> > Cc: emacs-devel@gnu.org > Date: Sat, 07 Nov 2015 09:32:36 +0100 > > > Let us officially freeze in one weeks, next Friday, Nov 13 at 11:59 PM > > UTC, so that any ready, last minute features can get in before 25.1 is > > closed. > > That sounds like a free-for-all. With the development cycles of Emacs, > rushing in last-minute features might come at costs of half a year. Why is that a problem? We are in no rush to have another major release. On the contrary, IMO having a major release with no major new features is not a good idea. Emacs 25.1 shouldn't be anything like 24.6 could have been. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 (was: Dynamic loading progress) 2015-11-07 1:53 ` Feature freezes and Emacs 25 (was: Dynamic loading progress) John Wiegley 2015-11-07 8:32 ` Feature freezes and Emacs 25 David Kastrup @ 2015-11-07 8:33 ` Eli Zaretskii 2015-11-09 21:55 ` Feature freezes and Emacs 25 John Wiegley 2015-11-07 10:59 ` Phillip Lord 2015-11-07 14:20 ` kqueue in Emacs 25.1? (was: Feature freezes and Emacs 25) Michael Albinus 3 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-07 8:33 UTC (permalink / raw) To: John Wiegley; +Cc: emacs-devel > From: John Wiegley <jwiegley@gmail.com> > Cc: emacs-devel@gnu.org > Date: Fri, 06 Nov 2015 20:53:19 -0500 > > Let us officially freeze in one weeks, next Friday, Nov 13 at 11:59 PM UTC, so > that any ready, last minute features can get in before 25.1 is closed. Then > we'll take a pause and review whether anything should be allowed after the > freeze. Once we're comfortable with the bug situation, we release. I think we should first decide whether new features that are "almost ready" should or should not be in 25.1. Two examples that immediately come to mind are dynamic loading and xwidgets; I don't know if there are others. After we make the decision, we could see if one week's time is enough. > I'd like to take a somewhat generous period for bug fixes, with feature work > happening in the meanwhile on topic branches. All severe bugs should either be > closed, or consciously deferred, before letting 25 out the door. We used to cut a release branch fairly early in the pretest , certainly at least when the first pretest tarball is put on alpha.gnu.org. Does the above mean you want the pretest to be worked on on master instead? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-07 8:33 ` Feature freezes and Emacs 25 (was: Dynamic loading progress) Eli Zaretskii @ 2015-11-09 21:55 ` John Wiegley 2015-11-09 22:08 ` Dmitry Gutov ` (2 more replies) 0 siblings, 3 replies; 765+ messages in thread From: John Wiegley @ 2015-11-09 21:55 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel >>>>> Eli Zaretskii <eliz@gnu.org> writes: > I think we should first decide whether new features that are "almost ready" > should or should not be in 25.1. Two examples that immediately come to mind > are dynamic loading and xwidgets; I don't know if there are others. After we > make the decision, we could see if one week's time is enough. I'd like to see both of those in 25.1. Let's freeze this Friday, and take a step back. We have several courses open: 1. Decide that what we have now should become 24.6. 2. Decide it will become 25.1. 3. Decide that we want to bring in more features that aren't yet complete, and so push the freeze to a future date. > We used to cut a release branch fairly early in the pretest , certainly at > least when the first pretest tarball is put on alpha.gnu.org. Does the above > mean you want the pretest to be worked on on master instead? I'd actually like to know more about our current release flow, before having that discussion here. I don't know yet what I want in that respect. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-09 21:55 ` Feature freezes and Emacs 25 John Wiegley @ 2015-11-09 22:08 ` Dmitry Gutov 2015-11-10 18:17 ` Richard Stallman 2015-11-09 23:59 ` Xue Fuqiao 2015-11-11 0:17 ` Juri Linkov 2 siblings, 1 reply; 765+ messages in thread From: Dmitry Gutov @ 2015-11-09 22:08 UTC (permalink / raw) To: Eli Zaretskii, emacs-devel On 11/09/2015 11:55 PM, John Wiegley wrote: > Let's freeze this Friday, and take a step back. We have several courses open: > > 1. Decide that what we have now should become 24.6. That doesn't seem to be an option, simply considering that master has been 25.0.25 for quite a while. > 2. Decide it will become 25.1. > > 3. Decide that we want to bring in more features that aren't yet complete, > and so push the freeze to a future date. I'd like to see this happen, maybe for a few weeks, at least for xref.el (and maybe project.el, too). There are still unresolved questions and issues there, and not enough people participating in the design. By the way, John, would you join the "project.el semantics" discussion? I've pinged you there. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-09 22:08 ` Dmitry Gutov @ 2015-11-10 18:17 ` Richard Stallman 2015-11-10 18:23 ` Dmitry Gutov 0 siblings, 1 reply; 765+ messages in thread From: Richard Stallman @ 2015-11-10 18:17 UTC (permalink / raw) To: Dmitry Gutov; +Cc: eliz, emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > > Let's freeze this Friday, and take a step back. We have several courses open: > > > > 1. Decide that what we have now should become 24.6. > That doesn't seem to be an option, simply considering that master has > been 25.0.25 for quite a while. We don't have to be governed by that. It's easy enough to make a branch for 24.6. -- Dr Richard Stallman President, Free Software Foundation (gnu.org, fsf.org) Internet Hall-of-Famer (internethalloffame.org) Skype: No way! See stallman.org/skype.html. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-10 18:17 ` Richard Stallman @ 2015-11-10 18:23 ` Dmitry Gutov 2015-11-11 16:58 ` Richard Stallman 0 siblings, 1 reply; 765+ messages in thread From: Dmitry Gutov @ 2015-11-10 18:23 UTC (permalink / raw) To: rms; +Cc: eliz, emacs-devel On 11/10/2015 08:17 PM, Richard Stallman wrote: > We don't have to be governed by that. > It's easy enough to make a branch for 24.6. Yes, if you're prepared to ignore the third-party code that has Emacs version checks, declared dependencies on Emacs 25.1 in certain packages, and existing blog posts "what's going to be in Emacs 25". Which would be a bad decision, IMO. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-10 18:23 ` Dmitry Gutov @ 2015-11-11 16:58 ` Richard Stallman 0 siblings, 0 replies; 765+ messages in thread From: Richard Stallman @ 2015-11-11 16:58 UTC (permalink / raw) To: Dmitry Gutov; +Cc: eliz, emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > Yes, if you're prepared to ignore the third-party code that has Emacs > version checks, declared dependencies on Emacs 25.1 in certain packages, It won't be harder to change those than it was to insert them. > and existing blog posts "what's going to be in Emacs 25". They won't be wrong -- anything installed already will still be in Emacs 25. -- Dr Richard Stallman President, Free Software Foundation (gnu.org, fsf.org) Internet Hall-of-Famer (internethalloffame.org) Skype: No way! See stallman.org/skype.html. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-09 21:55 ` Feature freezes and Emacs 25 John Wiegley 2015-11-09 22:08 ` Dmitry Gutov @ 2015-11-09 23:59 ` Xue Fuqiao 2015-11-10 0:07 ` John Wiegley 2015-11-11 0:17 ` Juri Linkov 2 siblings, 1 reply; 765+ messages in thread From: Xue Fuqiao @ 2015-11-09 23:59 UTC (permalink / raw) To: Emacs-devel; +Cc: Eli Zaretskii On Tue, Nov 10, 2015 at 5:55 AM, John Wiegley <jwiegley@gmail.com> wrote: > Let's freeze this Friday, and take a step back. We have several courses open: > > 1. Decide that what we have now should become 24.6. There is no plan for a new Emacs 24 release, unless some critical security vulnerabilities arise and need urgent fixing. > 2. Decide it will become 25.1. > > 3. Decide that we want to bring in more features that aren't yet complete, > and so push the freeze to a future date. > >> We used to cut a release branch fairly early in the pretest , certainly at >> least when the first pretest tarball is put on alpha.gnu.org. Does the above >> mean you want the pretest to be worked on on master instead? > > I'd actually like to know more about our current release flow, before having > that discussion here. I don't know yet what I want in that respect. In case you don't know, here is the new versioning scheme for GNU Emacs: https://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00872.html Actually, I think we should document our release process more explicitly. `admin/FOR-RELEASE' and `admin/notes/versioning' are not enough. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-09 23:59 ` Xue Fuqiao @ 2015-11-10 0:07 ` John Wiegley 2015-11-10 8:41 ` Xue Fuqiao 2015-11-10 9:41 ` Nicolas Petton 0 siblings, 2 replies; 765+ messages in thread From: John Wiegley @ 2015-11-10 0:07 UTC (permalink / raw) To: Xue Fuqiao; +Cc: Eli Zaretskii, Emacs-devel >>>>> Xue Fuqiao <xfq.free@gmail.com> writes: > In case you don't know, here is the new versioning scheme for GNU Emacs: > https://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00872.html Ok, the freeze is for 25.1. > Actually, I think we should document our release process more > explicitly. `admin/FOR-RELEASE' and `admin/notes/versioning' are not > enough. I agree. Would you be willing to contribute some drafting? I myself am still unfamiliar with all of our procedures in this regard. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-10 0:07 ` John Wiegley @ 2015-11-10 8:41 ` Xue Fuqiao 2015-11-10 13:25 ` Xue Fuqiao 2015-11-10 9:41 ` Nicolas Petton 1 sibling, 1 reply; 765+ messages in thread From: Xue Fuqiao @ 2015-11-10 8:41 UTC (permalink / raw) To: Emacs-devel, Eli Zaretskii On Tue, Nov 10, 2015 at 8:07 AM, John Wiegley <jwiegley@gmail.com> wrote: >>>>>> Xue Fuqiao <xfq.free@gmail.com> writes: > >> In case you don't know, here is the new versioning scheme for GNU Emacs: >> https://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00872.html > > Ok, the freeze is for 25.1. > >> Actually, I think we should document our release process more >> explicitly. `admin/FOR-RELEASE' and `admin/notes/versioning' are not >> enough. > > I agree. Would you be willing to contribute some drafting? I myself am still > unfamiliar with all of our procedures in this regard. OK. I'll write a draft tomorrow (or later today). ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-10 8:41 ` Xue Fuqiao @ 2015-11-10 13:25 ` Xue Fuqiao 2015-11-10 17:42 ` Nicolas Petton ` (2 more replies) 0 siblings, 3 replies; 765+ messages in thread From: Xue Fuqiao @ 2015-11-10 13:25 UTC (permalink / raw) To: Emacs-devel; +Cc: rgm, Eli Zaretskii, nicolas [-- Attachment #1: Type: text/plain, Size: 3806 bytes --] >>> Actually, I think we should document our release process more >>> explicitly. `admin/FOR-RELEASE' and `admin/notes/versioning' are not >>> enough. >> >> I agree. Would you be willing to contribute some drafting? I myself am still >> unfamiliar with all of our procedures in this regard. I just wrote a draft document for our release process. Please see the attached patches. I'm not quite familiar with the release process either, and the process was written merely by impression. I think Nicolas and Glenn are more familiar with the release process, so I just added them to the Cc list. Comments are warmly welcomed. The first patch renamed `admin/FOR-RELEASE' to `admin/RELEASE-PROCESS', and removed the trailing whitespace[1]. The second patch documents the release process in `admin/RELEASE-PROCESS'. There are things I would like to write, but didn't write for various reasons: 1. Document when to remove obsolete features. For example, "if a feature is declared obsolete in version `major.minor', it will continue to work in versions `major.minor' and `major+1.minor' but raise warnings, and it will be removed in version `major+2.minor'". I don't think we have a policy for removing obsolete features currently, but IMHO it would be good to have one. 2. Document what to do if a bug needs to be addressed in the next release (a.k.a. release-critical bugs). For example, how to set the bug meta-data for release-critical bugs, what meta-data to set, the criteria for release-critical bugs, etc. I didn't write this because I don't know how. Patches/suggestions are very welcome. 3. Document the number of pretest and RC releases we need to make for a release, or how to decide the number pretest/RC releases for a release. I didn't document this because I don't know the policy about this (if any). 4. Document how to coordinate with the release schedule of packages like Org and Gnus. I didn't write this because I'm not familiar with the process. Again, patches/suggestions are very welcome. 5. Add information about uploading the Windows binary to https://ftp.gnu.org/gnu/emacs/windows/, in `admin/make-tarball.txt'. I didn't write this because I'm not familiar with the process. Patches are welcome. 6. Document the criteria for feature freeze, i.e., when should we freeze the master branch? I didn't write this because we don't have a policy for this currently. 7. Things related to people. Such as: * Who is in charge of a release? * Who may make a good candidate for an RM (release manager)? In addition, I have some suggestions about our current release process and versioning scheme: * IMHO the current status of Emacs development should be present somewhere, for those who don't follow emacs-devel closely. Something like this would be a good start: https://wiki.documentfoundation.org/ReleasePlan/5.1#5.1.0_release * I think we need to encourage developers to prioritize bugs during phase two and/or phase three in the release cycle (see my patches for the three phases). It will make the quality of the new release better, or at least give developers an overview of the general development (bugfix) direction. * Currently, the version of an RC release (returned by `(emacs-version)') is the same as a stable release, but as a user, sometimes I can't tell if I'm using a stable version of Emacs or a release candidate. I still think something like 25.1-rc1 is better than 25.1, because it's clearer. The release process I wrote applies mainly to a new major release (such as 25.1) instead of a minor release (such as 24.5). So the documents still need expanding. Comments? [1] My `pre-commit' hook won't let me commit if I don't remove the trailing whitespace ;-) [-- Attachment #2: 0001-admin-RELEASE-PROCESS-Rename-from-admin-FOR-RELEASE.patch --] [-- Type: application/octet-stream, Size: 18088 bytes --] From 912b6e01bcea785928642fc6240fbb7d4bc1ea31 Mon Sep 17 00:00:00 2001 From: Xue Fuqiao <xfq.free@gmail.com> Date: Tue, 10 Nov 2015 16:55:05 +0800 Subject: [PATCH 1/2] * admin/RELEASE-PROCESS: Rename from admin/FOR-RELEASE. --- admin/FOR-RELEASE | 282 -------------------------------------------------- admin/RELEASE-PROCESS | 282 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 282 insertions(+), 282 deletions(-) delete mode 100644 admin/FOR-RELEASE create mode 100644 admin/RELEASE-PROCESS diff --git a/admin/FOR-RELEASE b/admin/FOR-RELEASE deleted file mode 100644 index 6ecec89..0000000 --- a/admin/FOR-RELEASE +++ /dev/null @@ -1,282 +0,0 @@ -Tasks needed before the next release. - -* TO BE DONE SHORTLY BEFORE RELEASE - -** Make sure the necessary sources and scripts for any generated files -are included in the source tarfile. (They don't need to be installed, -so eg admin/ is fine.) - -** Manuals -Check for node names using problematic characters: - find doc -name '*.texi' -exec grep '^@node[^,]*[:.()]' {} + -Sadly makeinfo does not warn about such characters. - -Check for major new features added since the last release (e.g. new -lisp files), and add the relevant authors to the Acknowledgments in -doc/emacs/ack.texi and emacs.texi. - -Check cross-references between the manuals (eg from emacs to elisp) -are correct. You can use something like the following in the info -directory in the Emacs build tree: - -emacs -Q --eval "(progn (require 'info) (setq Info-directory-list '(\".\")))" \ - -f info-xref-check-all - -Setting Info-directory-list avoids having system info pages confuse -things. References to external manuals will be flagged as -uncheckable. You should still check these, and also that each -external manual has an appropriate redirect in the file manual/.htaccess -in the web pages repository. E.g.: -Redirect /software/emacs/manual/html_mono/automake.html /software/automake/manual/automake.html -Redirect /software/emacs/manual/html_node/automake/ /software/automake/manual/html_node/ - -Another tool you can use to check links is gnu.org's linc.py: -http://www.gnu.org/server/source/ - -You run this something like: - -cd /path/to/cvs/emacs-www -linc.py -o /path/to/output-dir --url http://www.gnu.org/software/emacs/ . - -Be warned that it is really, really slow (as in, can take ~ a full day -to check the manual/ directory). It is probably best to run it on a -single directory at a time from eg manual/html_node. It is very -inefficient, but may reveal a few things that info-xref does not. - - -make emacs.dvi, elisp.dvi, and deal with any errors (undefined -references etc) in the output. Break any overfull lines. -Underfull hboxes are not serious, but it can be nice to get rid of -them if a simple rephrasing or rearrangement will work. - -Update the master menu and detailed menu (eg the antinews version). -The command texinfo-multiple-files-update can do this, but you -probably want to apply the results selectively (eg the current master -menu has better line-breaks than the automatic version). It includes -the menu-entry name (if there is one) as well as the node name - using -only the latter looks better. Also, it doesn't seem to handle nested -includes, so will miss edebug.texi etc. - -Check for widow and orphan lines in the printed manual; make sure all -the pages really look ok in the manual as formatted. Orphans/widows -are cases where the first/last line of a paragraph is on its own at -the end/start of a page, or where the last word in a paragraph is on -its own at the start of a line. It looks better if you reword/respace -things to avoid these. (AFAIK, there is no way to find these except -paging through the whole manual.) This should be the very last thing -you do, since any change can alter the layout. -(Actually, there is probably little point in trying to do this. -It's only really relevant if printed versions of the manuals are going -to be published. End-users are not likely to print out all 1000+ -pages of the manuals, and even if they do, the resulting page breaks -depend on what paper and font size they use. This also means that if -you _are_ going to do this, it should be done with the paper and font -size that the GNU Press are going to use when they print the manuals. -I think this is different to what you get if you just use eg 'make -emacs.pdf' (e.g., enable "smallbook"). - -** Check the keybindings in the refcards are correct, and add any new ones. -What paper size are the English versions supposed to be on? -On Debian testing, the packages texlive-lang-czechslovak and -texlive-lang-polish will let you generate the cs-* and sk-* pdfs. -(You may need texlive-lang-cyrillic, texlive-lang-german for others.) -The Makefile rules did not work for me, I had to use something like: -csplain -output-format=pdf cs-refcard - -** Ask maintainers of refcard translations to update them. - -Emacs 22 translators: - -LANG Translator Status -cs Pavel Janík -de Sven Joachim -fr Eric Jacoboni -pl Włodek Bzyl -pt-br Rodrigo Real -ru Alex Ott -sk Miroslav Vaško - -** For a major release, add a "New in Emacs XX" section to faq.texi. - -** Remove temporary +++/--- lines in NEWS. - -** Try to reorder NEWS: most important things first, related items together. - -** Consider bumping customize-changed-options-previous-release. - -** cusver-check from admin.el can help find new defcustoms missing -:version tags. - -** Add a line to etc/HISTORY for the release version number and date. - -* BUGS - -** Check for modes which bind M-s that conflicts with a new global binding M-s -and change key bindings where necessary. The current list of modes: - -1. Gnus binds 'M-s' to 'gnus-summary-search-article-forward'. - -2. Minibuffer binds 'M-s' to 'next-matching-history-element' - (not useful any more since C-s can now search in the history). - -3. 'center-line' in Text mode was already moved to the text formatting - keymap as 'M-o M-s' (thus this binding is not necessary any more - in 'nroff-mode-map' too and can be removed now from the nroff mode - because it can now use the global key binding 'M-o M-s' 'center-line'). - -4. PCL-CVS binds 'M-s' to 'cvs-status', and log-edit-mode binds it to - 'log-edit-comment-search-forward'. Perhaps search commands - on the global key binding 'M-s' are useless in these modes. - -5. Rmail binds '\es' to 'rmail-search'/'rmail-summary-search'. - - -* DOCUMENTATION - -** Check the Emacs Tutorial. - -The first line of every tutorial must begin with text ending in a -period (".", ASCII 0x2E) saying "Emacs Tutorial" in the respective -language. This should be followed by "See end for copying conditions", -likewise in the respective language. - -After each file name, on the same line or the following line, come the -names of the people who have checked it. - -SECTION READERS ----------------------------------- -TUTORIAL cyd -TUTORIAL.bg ogi -TUTORIAL.cn xfq -TUTORIAL.cs -TUTORIAL.de wl -TUTORIAL.eo -TUTORIAL.es -TUTORIAL.fr -TUTORIAL.he eliz -TUTORIAL.it -TUTORIAL.ja -TUTORIAL.ko -TUTORIAL.nl Pieter Schoenmakers -TUTORIAL.pl -TUTORIAL.pt_BR -TUTORIAL.ro -TUTORIAL.ru Alex Ott -TUTORIAL.sk -TUTORIAL.sl Primoz PETERLIN -TUTORIAL.sv Mats Lidell -TUTORIAL.th -TUTORIAL.zh - -** Check the manual. - -abbrevs.texi -ack.texi -anti.texi -arevert-xtra.texi -basic.texi -buffers.texi -building.texi -calendar.texi -cal-xtra.texi -cmdargs.texi -commands.texi -custom.texi -dired.texi -dired-xtra.texi -display.texi -emacs.texi -emacs-xtra.texi -emerge-xtra.texi -entering.texi -files.texi -fixit.texi -fortran-xtra.texi -frames.texi -glossary.texi -help.texi -indent.texi -killing.texi -kmacro.texi -macos.texi -maintaining.texi -mark.texi -mini.texi -misc.texi -modes.texi -msdos.texi -msdos-xtra.texi -mule.texi -m-x.texi -package.texi -picture-xtra.texi -programs.texi -regs.texi -rmail.texi -screen.texi -search.texi -sending.texi -text.texi -trouble.texi -vc-xtra.texi -vc1-xtra.texi -windows.texi -xresources.texi - -** Check the Lisp manual. - -abbrevs.texi -anti.texi -back.texi -backups.texi -buffers.texi -commands.texi -compile.texi -control.texi -customize.texi -debugging.texi -display.texi -edebug.texi -elisp.texi -errors.texi -eval.texi -files.texi -frames.texi -functions.texi -hash.texi -help.texi -hooks.texi -index.texi -internals.texi -intro.texi -keymaps.texi -lists.texi -loading.texi -macros.texi -maps.texi -markers.texi -minibuf.texi -modes.texi -nonascii.texi -numbers.texi Paul Eggert (24.4) -objects.texi -os.texi -package.texi -positions.texi -processes.texi -searching.texi -sequences.texi -streams.texi -strings.texi -symbols.texi -syntax.texi -text.texi -tips.texi -variables.texi -windows.texi - -\f -Local variables: -mode: outline -coding: utf-8 -end: diff --git a/admin/RELEASE-PROCESS b/admin/RELEASE-PROCESS new file mode 100644 index 0000000..286b90e --- /dev/null +++ b/admin/RELEASE-PROCESS @@ -0,0 +1,282 @@ +Tasks needed before the next release. + +* TO BE DONE SHORTLY BEFORE RELEASE + +** Make sure the necessary sources and scripts for any generated files +are included in the source tarfile. (They don't need to be installed, +so eg admin/ is fine.) + +** Manuals +Check for node names using problematic characters: + find doc -name '*.texi' -exec grep '^@node[^,]*[:.()]' {} + +Sadly makeinfo does not warn about such characters. + +Check for major new features added since the last release (e.g. new +lisp files), and add the relevant authors to the Acknowledgments in +doc/emacs/ack.texi and emacs.texi. + +Check cross-references between the manuals (eg from emacs to elisp) +are correct. You can use something like the following in the info +directory in the Emacs build tree: + +emacs -Q --eval "(progn (require 'info) (setq Info-directory-list '(\".\")))" \ + -f info-xref-check-all + +Setting Info-directory-list avoids having system info pages confuse +things. References to external manuals will be flagged as +uncheckable. You should still check these, and also that each +external manual has an appropriate redirect in the file manual/.htaccess +in the web pages repository. E.g.: +Redirect /software/emacs/manual/html_mono/automake.html /software/automake/manual/automake.html +Redirect /software/emacs/manual/html_node/automake/ /software/automake/manual/html_node/ + +Another tool you can use to check links is gnu.org's linc.py: +http://www.gnu.org/server/source/ + +You run this something like: + +cd /path/to/cvs/emacs-www +linc.py -o /path/to/output-dir --url http://www.gnu.org/software/emacs/ . + +Be warned that it is really, really slow (as in, can take ~ a full day +to check the manual/ directory). It is probably best to run it on a +single directory at a time from eg manual/html_node. It is very +inefficient, but may reveal a few things that info-xref does not. + + +make emacs.dvi, elisp.dvi, and deal with any errors (undefined +references etc) in the output. Break any overfull lines. +Underfull hboxes are not serious, but it can be nice to get rid of +them if a simple rephrasing or rearrangement will work. + +Update the master menu and detailed menu (eg the antinews version). +The command texinfo-multiple-files-update can do this, but you +probably want to apply the results selectively (eg the current master +menu has better line-breaks than the automatic version). It includes +the menu-entry name (if there is one) as well as the node name - using +only the latter looks better. Also, it doesn't seem to handle nested +includes, so will miss edebug.texi etc. + +Check for widow and orphan lines in the printed manual; make sure all +the pages really look ok in the manual as formatted. Orphans/widows +are cases where the first/last line of a paragraph is on its own at +the end/start of a page, or where the last word in a paragraph is on +its own at the start of a line. It looks better if you reword/respace +things to avoid these. (AFAIK, there is no way to find these except +paging through the whole manual.) This should be the very last thing +you do, since any change can alter the layout. +(Actually, there is probably little point in trying to do this. +It's only really relevant if printed versions of the manuals are going +to be published. End-users are not likely to print out all 1000+ +pages of the manuals, and even if they do, the resulting page breaks +depend on what paper and font size they use. This also means that if +you _are_ going to do this, it should be done with the paper and font +size that the GNU Press are going to use when they print the manuals. +I think this is different to what you get if you just use eg 'make +emacs.pdf' (e.g., enable "smallbook"). + +** Check the keybindings in the refcards are correct, and add any new ones. +What paper size are the English versions supposed to be on? +On Debian testing, the packages texlive-lang-czechslovak and +texlive-lang-polish will let you generate the cs-* and sk-* pdfs. +(You may need texlive-lang-cyrillic, texlive-lang-german for others.) +The Makefile rules did not work for me, I had to use something like: +csplain -output-format=pdf cs-refcard + +** Ask maintainers of refcard translations to update them. + +Emacs 22 translators: + +LANG Translator Status +cs Pavel Janík +de Sven Joachim +fr Eric Jacoboni +pl Włodek Bzyl +pt-br Rodrigo Real +ru Alex Ott +sk Miroslav Vaško + +** For a major release, add a "New in Emacs XX" section to faq.texi. + +** Remove temporary +++/--- lines in NEWS. + +** Try to reorder NEWS: most important things first, related items together. + +** Consider bumping customize-changed-options-previous-release. + +** cusver-check from admin.el can help find new defcustoms missing +:version tags. + +** Add a line to etc/HISTORY for the release version number and date. + +* BUGS + +** Check for modes which bind M-s that conflicts with a new global binding M-s +and change key bindings where necessary. The current list of modes: + +1. Gnus binds 'M-s' to 'gnus-summary-search-article-forward'. + +2. Minibuffer binds 'M-s' to 'next-matching-history-element' + (not useful any more since C-s can now search in the history). + +3. 'center-line' in Text mode was already moved to the text formatting + keymap as 'M-o M-s' (thus this binding is not necessary any more + in 'nroff-mode-map' too and can be removed now from the nroff mode + because it can now use the global key binding 'M-o M-s' 'center-line'). + +4. PCL-CVS binds 'M-s' to 'cvs-status', and log-edit-mode binds it to + 'log-edit-comment-search-forward'. Perhaps search commands + on the global key binding 'M-s' are useless in these modes. + +5. Rmail binds '\es' to 'rmail-search'/'rmail-summary-search'. + + +* DOCUMENTATION + +** Check the Emacs Tutorial. + +The first line of every tutorial must begin with text ending in a +period (".", ASCII 0x2E) saying "Emacs Tutorial" in the respective +language. This should be followed by "See end for copying conditions", +likewise in the respective language. + +After each file name, on the same line or the following line, come the +names of the people who have checked it. + +SECTION READERS +---------------------------------- +TUTORIAL cyd +TUTORIAL.bg ogi +TUTORIAL.cn xfq +TUTORIAL.cs +TUTORIAL.de wl +TUTORIAL.eo +TUTORIAL.es +TUTORIAL.fr +TUTORIAL.he eliz +TUTORIAL.it +TUTORIAL.ja +TUTORIAL.ko +TUTORIAL.nl Pieter Schoenmakers +TUTORIAL.pl +TUTORIAL.pt_BR +TUTORIAL.ro +TUTORIAL.ru Alex Ott +TUTORIAL.sk +TUTORIAL.sl Primoz PETERLIN +TUTORIAL.sv Mats Lidell +TUTORIAL.th +TUTORIAL.zh + +** Check the manual. + +abbrevs.texi +ack.texi +anti.texi +arevert-xtra.texi +basic.texi +buffers.texi +building.texi +calendar.texi +cal-xtra.texi +cmdargs.texi +commands.texi +custom.texi +dired.texi +dired-xtra.texi +display.texi +emacs.texi +emacs-xtra.texi +emerge-xtra.texi +entering.texi +files.texi +fixit.texi +fortran-xtra.texi +frames.texi +glossary.texi +help.texi +indent.texi +killing.texi +kmacro.texi +macos.texi +maintaining.texi +mark.texi +mini.texi +misc.texi +modes.texi +msdos.texi +msdos-xtra.texi +mule.texi +m-x.texi +package.texi +picture-xtra.texi +programs.texi +regs.texi +rmail.texi +screen.texi +search.texi +sending.texi +text.texi +trouble.texi +vc-xtra.texi +vc1-xtra.texi +windows.texi +xresources.texi + +** Check the Lisp manual. + +abbrevs.texi +anti.texi +back.texi +backups.texi +buffers.texi +commands.texi +compile.texi +control.texi +customize.texi +debugging.texi +display.texi +edebug.texi +elisp.texi +errors.texi +eval.texi +files.texi +frames.texi +functions.texi +hash.texi +help.texi +hooks.texi +index.texi +internals.texi +intro.texi +keymaps.texi +lists.texi +loading.texi +macros.texi +maps.texi +markers.texi +minibuf.texi +modes.texi +nonascii.texi +numbers.texi Paul Eggert (24.4) +objects.texi +os.texi +package.texi +positions.texi +processes.texi +searching.texi +sequences.texi +streams.texi +strings.texi +symbols.texi +syntax.texi +text.texi +tips.texi +variables.texi +windows.texi + +\f +Local variables: +mode: outline +coding: utf-8 +end: -- 2.6.3 [-- Attachment #3: 0002-Document-the-release-process.patch --] [-- Type: application/octet-stream, Size: 4943 bytes --] From 56de66dfc2547b58ec97829cea873de9653736e3 Mon Sep 17 00:00:00 2001 From: Xue Fuqiao <xfq.free@gmail.com> Date: Tue, 10 Nov 2015 17:46:51 +0800 Subject: [PATCH 2/2] Document the release process * admin/notes/versioning: Add information about RC releases. * admin/RELEASE-PROCESS: Document the release process. * admin/authors.el (authors-ignored-files): * admin/README: Change FOR-RELEASE to RELEASE-PROCESS. --- admin/README | 4 ++-- admin/RELEASE-PROCESS | 45 ++++++++++++++++++++++++++++++++++++++++++++- admin/authors.el | 2 +- admin/notes/versioning | 11 +++++++---- 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/admin/README b/admin/README index 2286e35..22c72f4 100644 --- a/admin/README +++ b/admin/README @@ -12,9 +12,9 @@ what you do when using them. * Instructions and scripts used to prepare an Emacs release. -** FOR-RELEASE +** RELEASE-PROCESS -Living list of activities that must be completed before the next release. +The release process used by GNU Emacs. ** make-tarball.txt diff --git a/admin/RELEASE-PROCESS b/admin/RELEASE-PROCESS index 286b90e..672cab4 100644 --- a/admin/RELEASE-PROCESS +++ b/admin/RELEASE-PROCESS @@ -1,7 +1,43 @@ -Tasks needed before the next release. +This document describes the release process used by GNU Emacs. + +* RELEASE CYCLE + +Each release cycle will be split into three periods. + +** Phase one: development + +The first phase of the release schedule is the "heads-down" working +period for new features. + +** Phase two: feature freeze + +Shortly before the feature freeze, Emacs developers will be devoted to +figuring out what features to include in the next release and what +features to defer to a later release. + +During the feature freeze, no new features will be accepted in +`master'. It ensures that sufficient share of the release cycle is +dedicated to QA. + +When the feature freeze is over, a release branch called "emacs-NN" +("NN" represents the major version number of the new Emacs release) +will be cut from `master'. + +** Phase three: bugfixes + +The last phase of a release cycle is spent fixing bugs and eliminating +undocumented new features on the "emacs-NN" branch. + +In parallel to this phase, `master' can receive new features, to be +released in the next release cycle. From time to time, the master +branches merges bugfix commits from the "emacs-NN" branch. * TO BE DONE SHORTLY BEFORE RELEASE +** Make sure the Copyright date reflects the current year in the source +files. See `admin/notes/years' for information about maintaining +copyright years for GNU Emacs. + ** Make sure the necessary sources and scripts for any generated files are included in the source tarfile. (They don't need to be installed, so eg admin/ is fine.) @@ -275,6 +311,13 @@ tips.texi variables.texi windows.texi +* OTHER INFORMATION + +For Emacs's versioning scheme, see `admin/notes/versioning'. + +For instructions to create pretest or release tarballs, announcements, +etc., see `admin/make-tarball.txt'. + \f Local variables: mode: outline diff --git a/admin/authors.el b/admin/authors.el index 3d7850a..f5d23be 100644 --- a/admin/authors.el +++ b/admin/authors.el @@ -267,7 +267,7 @@ authors-ignored-files '("external-lisp" "lock" "share-lib" "local-lisp" "noleim-Makefile.in" - "NEWS" "ORDERS" "PROBLEMS" "FAQ" "AUTHORS" "FOR-RELEASE" "TODO" "todo" + "NEWS" "ORDERS" "PROBLEMS" "FAQ" "AUTHORS" "RELEASE-PROCESS" "TODO" "todo" "MACHINES" "SERVICE" "README.unicode" "README.multi-tty" "TUTORIAL.translators" "NEWS.unicode" "COPYING.DJ" "Makefile.old" "Makefile.am" diff --git a/admin/notes/versioning b/admin/notes/versioning index e422b22..e956a68 100644 --- a/admin/notes/versioning +++ b/admin/notes/versioning @@ -9,16 +9,19 @@ Emacs version numbers have the form "build" increments each time Emacs is built in the same location (without cleaning) and isn't really part of the version. -bugfix releases increase "minor" by 1. -non-bugfix releases increase "major" by 1, and reset "minor" to 1. +Bugfix releases increase "minor" by 1. +Non-bugfix releases increase "major" by 1, and reset "minor" to 1. (The division between bugfix and non-bugfix has not always been clear historically.) Unreleased (development) versions have an extra "devel" component. This is a fairly meaningless number that may be unchanged for a long time. It is normally 50. -When the release process starts, it changes to 90, 91, ... -When the actual release is made, this component is removed. + +After we cut the release branch, we’ll make pretest and release +candidate (RC) releases. For pretest releases, the "devel" component +changes to 90, 91, ... When the first RC release is made, this +component is removed. The development version for a new major release has "minor" = 0. The development version for a new minor release has "minor" = that of -- 2.6.3 ^ permalink raw reply related [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-10 13:25 ` Xue Fuqiao @ 2015-11-10 17:42 ` Nicolas Petton 2015-11-10 17:50 ` Eli Zaretskii 2015-11-11 19:59 ` Glenn Morris 2 siblings, 0 replies; 765+ messages in thread From: Nicolas Petton @ 2015-11-10 17:42 UTC (permalink / raw) To: Xue Fuqiao, Emacs-devel; +Cc: rgm, Eli Zaretskii [-- Attachment #1: Type: text/plain, Size: 450 bytes --] Xue Fuqiao <xfq.free@gmail.com> writes: > I just wrote a draft document for our release process. Please see the > attached patches. I'm not quite familiar with the release process > either, and the process was written merely by impression. I think > Nicolas and Glenn are more familiar with the release process, so I just > added them to the Cc list. Comments are warmly welcomed. Thanks, I'll take the time to review your patch shortly. Nico [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 512 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-10 13:25 ` Xue Fuqiao 2015-11-10 17:42 ` Nicolas Petton @ 2015-11-10 17:50 ` Eli Zaretskii 2015-11-10 18:13 ` Drew Adams 2015-11-11 1:53 ` Xue Fuqiao 2015-11-11 19:59 ` Glenn Morris 2 siblings, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-10 17:50 UTC (permalink / raw) To: Xue Fuqiao; +Cc: rgm, nicolas, emacs-devel > Date: Tue, 10 Nov 2015 21:25:33 +0800 > From: Xue Fuqiao <xfq.free@gmail.com> > Cc: Eli Zaretskii <eliz@gnu.org>, nicolas@petton.fr, rgm@gnu.org > > I just wrote a draft document for our release process. Please see the > attached patches. Thanks! > The first patch renamed `admin/FOR-RELEASE' to `admin/RELEASE-PROCESS', Please grep all the repository for references to FOR-RELEASE. At least admin/notes/bugtracker still does. > 1. Document when to remove obsolete features. For example, "if a > feature is declared obsolete in version `major.minor', it will > continue to work in versions `major.minor' and `major+1.minor' but > raise warnings, and it will be removed in version `major+2.minor'". > I don't think we have a policy for removing obsolete features > currently, but IMHO it would be good to have one. I'm not sure a fixed policy of this kind is possible. Minor features can be removed quickly, not-so-minor ones not so quickly. > 2. Document what to do if a bug needs to be addressed in the next > release (a.k.a. release-critical bugs). For example, how to set the > bug meta-data for release-critical bugs, what meta-data to set, the > criteria for release-critical bugs, etc. I didn't write this because > I don't know how. Patches/suggestions are very welcome. http://lists.gnu.org/archive/html/emacs-devel/2015-02/msg00226.html > 3. Document the number of pretest and RC releases we need to make for a > release, or how to decide the number pretest/RC releases for a > release. I didn't document this because I don't know the policy > about this (if any). There is no policy, and I don't think there could be. It depends on the number of bugs reported during the pretest, which in turn depends on how many radically new features were added. E.g., Emacs 21.1 had something like 15 pretests, IIRC. > * IMHO the current status of Emacs development should be present > somewhere, for those who don't follow emacs-devel closely. Something > like this would be a good start: > https://wiki.documentfoundation.org/ReleasePlan/5.1#5.1.0_release That's not status, that's plan. See the discussion about cadence model for what I think about that in conjunction with Emacs. > * I think we need to encourage developers to prioritize bugs during > phase two and/or phase three in the release cycle (see my patches for > the three phases). It will make the quality of the new release > better, or at least give developers an overview of the general > development (bugfix) direction. Not sure what you mean by "prioritize bugs". Do you mean priorities among bugs? That will only help if there are enough people who work on fixing bugs, and we want to employ those resources more efficiently. > * Currently, the version of an RC release (returned by > `(emacs-version)') is the same as a stable release, but as a user, > sometimes I can't tell if I'm using a stable version of Emacs or a > release candidate. I still think something like 25.1-rc1 is better > than 25.1, because it's clearer. Actually, we almost never made release candidates. > [1] My `pre-commit' hook won't let me commit if I don't remove the > trailing whitespace ;-) There's the --no-verify switch to "git commit". > +** Phase two: feature freeze I think we should discuss this and understand better why this is needed and what are its entry and exit conditions. > +Shortly before the feature freeze, Emacs developers will be devoted to > +figuring out what features to include in the next release and what > +features to defer to a later release. If the feature is already on master, we don't have any easy way of removing it. Nor should we, IMO. > +After we cut the release branch, we’ll make pretest and release > +candidate (RC) releases. For pretest releases, the "devel" component > +changes to 90, 91, ... The number of the first pretest version is not carved in stone. It depends on the developers' estimation of how close we are to the release. E.g., Emacs 21.1 had its first pretest called 21.0.70, AFAIR. Thanks again for working on this. ^ permalink raw reply [flat|nested] 765+ messages in thread
* RE: Feature freezes and Emacs 25 2015-11-10 17:50 ` Eli Zaretskii @ 2015-11-10 18:13 ` Drew Adams 2015-11-11 16:57 ` Richard Stallman 2015-11-11 1:53 ` Xue Fuqiao 1 sibling, 1 reply; 765+ messages in thread From: Drew Adams @ 2015-11-10 18:13 UTC (permalink / raw) To: Eli Zaretskii, Xue Fuqiao; +Cc: rgm, nicolas, emacs-devel > > 1. Document when to remove obsolete features. For example, "if a > > feature is declared obsolete in version `major.minor', it will > > continue to work in versions `major.minor' and `major+1.minor' but > > raise warnings, and it will be removed in version `major+2.minor'". > > I don't think we have a policy for removing obsolete features > > currently, but IMHO it would be good to have one. > > I'm not sure a fixed policy of this kind is possible. Minor features > can be removed quickly, not-so-minor ones not so quickly. There should _never_ be such a policy to remove an obsolete feature. Each deprecation, and each subsequent removal of its support, should be handled on a case-by-case basis. Anything else is madness. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-10 18:13 ` Drew Adams @ 2015-11-11 16:57 ` Richard Stallman 0 siblings, 0 replies; 765+ messages in thread From: Richard Stallman @ 2015-11-11 16:57 UTC (permalink / raw) To: Drew Adams; +Cc: xfq.free, rgm, eliz, nicolas, emacs-devel [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] I think we should wait years to remove obsolete features. Hurrying would increase the hassle this causes for users who like them, and we can afford to wait. -- Dr Richard Stallman President, Free Software Foundation (gnu.org, fsf.org) Internet Hall-of-Famer (internethalloffame.org) Skype: No way! See stallman.org/skype.html. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-10 17:50 ` Eli Zaretskii 2015-11-10 18:13 ` Drew Adams @ 2015-11-11 1:53 ` Xue Fuqiao 1 sibling, 0 replies; 765+ messages in thread From: Xue Fuqiao @ 2015-11-11 1:53 UTC (permalink / raw) To: Eli Zaretskii; +Cc: rgm, nicolas, Emacs-devel [-- Attachment #1: Type: text/plain, Size: 4351 bytes --] On Wed, Nov 11, 2015 at 1:50 AM, Eli Zaretskii <eliz@gnu.org> wrote: Hi Eli, > Please grep all the repository for references to FOR-RELEASE. At > least admin/notes/bugtracker still does. Fixed, thanks. I removed the reference to FOR-RELEASE in admin/notes/bugtracker, because I think all bugs found should be in the bug tracker, instead of having some of them in the RELEASE-PROCESS file. >> 1. Document when to remove obsolete features. For example, "if a >> feature is declared obsolete in version `major.minor', it will >> continue to work in versions `major.minor' and `major+1.minor' but >> raise warnings, and it will be removed in version `major+2.minor'". >> I don't think we have a policy for removing obsolete features >> currently, but IMHO it would be good to have one. > > I'm not sure a fixed policy of this kind is possible. Minor features > can be removed quickly, not-so-minor ones not so quickly. OK. >> 2. Document what to do if a bug needs to be addressed in the next >> release (a.k.a. release-critical bugs). For example, how to set the >> bug meta-data for release-critical bugs, what meta-data to set, the >> criteria for release-critical bugs, etc. I didn't write this because >> I don't know how. Patches/suggestions are very welcome. > > http://lists.gnu.org/archive/html/emacs-devel/2015-02/msg00226.html Thanks. I've made some changes about this in the new patch (attached). Furthermore, I hope we can get rid of the BUGS section in RELEASE-PROCESS and move it entirely to Debbugs. (BTW, I hope we can file a meta-bug, listing all release-tracking bugs like #19758 and #19759, and update it in each release, so that we don't have to update the RELEASE-CRITICAL BUGS section in every future release, and we can see our previous release-tracking bugs more conveniently.) >> * IMHO the current status of Emacs development should be present >> somewhere, for those who don't follow emacs-devel closely. Something >> like this would be a good start: >> https://wiki.documentfoundation.org/ReleasePlan/5.1#5.1.0_release > > That's not status, that's plan. See the discussion about cadence > model for what I think about that in conjunction with Emacs. OK, I'll see. >> * I think we need to encourage developers to prioritize bugs during >> phase two and/or phase three in the release cycle (see my patches for >> the three phases). It will make the quality of the new release >> better, or at least give developers an overview of the general >> development (bugfix) direction. > > Not sure what you mean by "prioritize bugs". I mean, adding severity level for bugs and adding blocking bugs. So the chance of important bugs missed in the new release will be reduced. This needs to be done in every phase, but is even more important in the bugfix phase. >> [1] My `pre-commit' hook won't let me commit if I don't remove the >> trailing whitespace ;-) > > There's the --no-verify switch to "git commit". Thanks for the hint Eli - you are right as usual. >> +** Phase two: feature freeze > > I think we should discuss this and understand better why this is > needed and what are its entry and exit conditions. I agree. John (and others)? Any comment on this? >> +Shortly before the feature freeze, Emacs developers will be devoted to >> +figuring out what features to include in the next release and what >> +features to defer to a later release. > > If the feature is already on master, we don't have any easy way of > removing it. Nor should we, IMO. That's not what I meant. I meant the long-term feature branches (concurrency/dynamic-modules/xwidget), and features still under discussion (xref/project?). >> +After we cut the release branch, we’ll make pretest and release >> +candidate (RC) releases. For pretest releases, the "devel" component >> +changes to 90, 91, ... > > The number of the first pretest version is not carved in stone. It > depends on the developers' estimation of how close we are to the > release. E.g., Emacs 21.1 had its first pretest called 21.0.70, > AFAIR. But IMHO having a consistent versioning scheme for pretests should better in the future. The estimation is somewhat subjective. Thanks for your review! [-- Attachment #2: 0002-Document-the-release-process.patch --] [-- Type: application/octet-stream, Size: 6437 bytes --] From 43f3db250aeea5c81556f7f624dcab87889c20e5 Mon Sep 17 00:00:00 2001 From: Xue Fuqiao <xfq.free@gmail.com> Date: Tue, 10 Nov 2015 17:46:51 +0800 Subject: [PATCH 2/2] Document the release process * admin/notes/versioning: Add information about RC releases. * admin/RELEASE-PROCESS: Document the release process. * admin/authors.el (authors-ignored-files): * admin/README: * CONTRIBUTE: Change FOR-RELEASE to RELEASE-PROCESS. --- CONTRIBUTE | 2 +- admin/README | 4 ++-- admin/RELEASE-PROCESS | 58 +++++++++++++++++++++++++++++++++++++++++++++++++- admin/authors.el | 2 +- admin/notes/bugtracker | 3 +-- admin/notes/versioning | 11 ++++++---- 6 files changed, 69 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTE b/CONTRIBUTE index 0ca5d0d..db1e35c 100644 --- a/CONTRIBUTE +++ b/CONTRIBUTE @@ -145,7 +145,7 @@ messages: will suffice. - There is no need to mention files such as NEWS, MAINTAINERS, and - FOR-RELEASE, or to indicate regeneration of files such as + RELEASE-PROCESS, or to indicate regeneration of files such as 'configure', in the ChangeLog entry. "There is no need" means you don't have to, but you can if you want to. diff --git a/admin/README b/admin/README index 2286e35..22c72f4 100644 --- a/admin/README +++ b/admin/README @@ -12,9 +12,9 @@ what you do when using them. * Instructions and scripts used to prepare an Emacs release. -** FOR-RELEASE +** RELEASE-PROCESS -Living list of activities that must be completed before the next release. +The release process used by GNU Emacs. ** make-tarball.txt diff --git a/admin/RELEASE-PROCESS b/admin/RELEASE-PROCESS index 286b90e..cf59184 100644 --- a/admin/RELEASE-PROCESS +++ b/admin/RELEASE-PROCESS @@ -1,7 +1,56 @@ -Tasks needed before the next release. +This document describes the release process used by GNU Emacs. + +* RELEASE CYCLE + +Each release cycle will be split into three periods. + +** Phase one: development + +The first phase of the release schedule is the "heads-down" working +period for new features. + +** Phase two: feature freeze + +Shortly before the feature freeze, Emacs developers will be devoted to +figuring out what features to include in the next release and what +features to defer to a later release. + +During the feature freeze, no new features will be accepted in +`master'. It ensures that sufficient share of the release cycle is +dedicated to QA. + +When the feature freeze is over, a release branch called "emacs-NN" +("NN" represents the major version number of the new Emacs release) +will be cut from `master'. + +** Phase three: bugfixes + +The last phase of a release cycle is spent fixing bugs and eliminating +undocumented new features on the "emacs-NN" branch. + +In parallel to this phase, `master' can receive new features, to be +released in the next release cycle. From time to time, the master +branches merges bugfix commits from the "emacs-NN" branch. + +* RELEASE-CRITICAL BUGS + +Emacs uses the "blocking bug(s)" feature of Debbugs for bugs need to +be addressed in the next release. + +Currently, bug#19759 is the tracking bug for release of 25.1. Say +bug#123 needs to be fixed for Emacs 25.1. Send a message to +control@debbugs.gnu.org that says: + + block 19759 by 123 + +Change "block" to "unblock" to unblock the bug. * TO BE DONE SHORTLY BEFORE RELEASE +** Make sure the Copyright date reflects the current year in the source +files. See `admin/notes/years' for information about maintaining +copyright years for GNU Emacs. + ** Make sure the necessary sources and scripts for any generated files are included in the source tarfile. (They don't need to be installed, so eg admin/ is fine.) @@ -275,6 +324,13 @@ tips.texi variables.texi windows.texi +* OTHER INFORMATION + +For Emacs's versioning scheme, see `admin/notes/versioning'. + +For instructions to create pretest or release tarballs, announcements, +etc., see `admin/make-tarball.txt'. + \f Local variables: mode: outline diff --git a/admin/authors.el b/admin/authors.el index 3d7850a..f5d23be 100644 --- a/admin/authors.el +++ b/admin/authors.el @@ -267,7 +267,7 @@ authors-ignored-files '("external-lisp" "lock" "share-lib" "local-lisp" "noleim-Makefile.in" - "NEWS" "ORDERS" "PROBLEMS" "FAQ" "AUTHORS" "FOR-RELEASE" "TODO" "todo" + "NEWS" "ORDERS" "PROBLEMS" "FAQ" "AUTHORS" "RELEASE-PROCESS" "TODO" "todo" "MACHINES" "SERVICE" "README.unicode" "README.multi-tty" "TUTORIAL.translators" "NEWS.unicode" "COPYING.DJ" "Makefile.old" "Makefile.am" diff --git a/admin/notes/bugtracker b/admin/notes/bugtracker index fb65bbe..3d6df03 100644 --- a/admin/notes/bugtracker +++ b/admin/notes/bugtracker @@ -140,8 +140,7 @@ you can add an element to gnus-posting-styles to do this automatically, eg: ** To record a bug in the tracker without sending mail to the bug list. This can be useful to make a note of something discussed on -emacs-devel that needs fixing. In other words, this can be the -equivalent of adding something to FOR-RELEASE. +emacs-devel that needs fixing. To: quiet@debbugs.gnu.org [headers end] diff --git a/admin/notes/versioning b/admin/notes/versioning index e422b22..e956a68 100644 --- a/admin/notes/versioning +++ b/admin/notes/versioning @@ -9,16 +9,19 @@ Emacs version numbers have the form "build" increments each time Emacs is built in the same location (without cleaning) and isn't really part of the version. -bugfix releases increase "minor" by 1. -non-bugfix releases increase "major" by 1, and reset "minor" to 1. +Bugfix releases increase "minor" by 1. +Non-bugfix releases increase "major" by 1, and reset "minor" to 1. (The division between bugfix and non-bugfix has not always been clear historically.) Unreleased (development) versions have an extra "devel" component. This is a fairly meaningless number that may be unchanged for a long time. It is normally 50. -When the release process starts, it changes to 90, 91, ... -When the actual release is made, this component is removed. + +After we cut the release branch, we’ll make pretest and release +candidate (RC) releases. For pretest releases, the "devel" component +changes to 90, 91, ... When the first RC release is made, this +component is removed. The development version for a new major release has "minor" = 0. The development version for a new minor release has "minor" = that of -- 2.6.3 ^ permalink raw reply related [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-10 13:25 ` Xue Fuqiao 2015-11-10 17:42 ` Nicolas Petton 2015-11-10 17:50 ` Eli Zaretskii @ 2015-11-11 19:59 ` Glenn Morris 2015-11-12 8:53 ` Xue Fuqiao 2 siblings, 1 reply; 765+ messages in thread From: Glenn Morris @ 2015-11-11 19:59 UTC (permalink / raw) To: Xue Fuqiao; +Cc: Eli Zaretskii, nicolas, Emacs-devel Xue Fuqiao wrote: > I just wrote a draft document for our release process. Please see the > attached patches. I'm not quite familiar with the release process > either, and the process was written merely by impression. I think > Nicolas and Glenn are more familiar with the release process, so I just > added them to the Cc list. Comments are warmly welcomed. I haven't read the draft, so the following comments are only on your email. > The first patch renamed `admin/FOR-RELEASE' to `admin/RELEASE-PROCESS', > and removed the trailing whitespace[1]. Does the (long-standing) name of the file really make a difference to anything? If you are going to rename it, you don't have to stick with an old-school SHOUTY name, you can use lower-case. In the following, there is no existing policy in many cases. IMO trying to document existing policy and create policy should be separate activities. Also I would resist the temptation to have a policy for _everything_. > 1. Document when to remove obsolete features. There's no existing policy, and this seems separate from making releases? The unofficial one is something like "there should normally be at least one major release between making something obsolete and removing it". (Personally I go with two.) > 2. Document what to do if a bug needs to be addressed in the next > release (a.k.a. release-critical bugs). Fix it? > For example, how to set the bug meta-data for release-critical bugs, > what meta-data to set, In the past we increased the severity of such bugs. Personally I felt this was a bad idea, http://lists.gnu.org/archive/html/emacs-devel/2015-02/msg00196.html so I unilaterally started using "block" for this. That thread explains how it works. No one else has shown any interest in tracking such things AFAIK. > 3. Document the number of pretest and RC releases we need to make for a > release, or how to decide the number pretest/RC releases for a > release. The "policy" is that there are as many pretests as needed until the code is of sufficient quality to release. A new pretest is made whenever there have been sufficient changes from the last one to warrant it. Normally, there is one RC, unless an unexpected last-minute problem occurs. > 4. Document how to coordinate with the release schedule of packages like > Org and Gnus. There is no policy. Personally I don't think one is needed. > 5. Add information about uploading the Windows binary to > https://ftp.gnu.org/gnu/emacs/windows/, in `admin/make-tarball.txt'. In exactly the same way anything else is uploaded to ftp.gnu.org? > 6. Document the criteria for feature freeze, i.e., when should we freeze > the master branch? This is up the lead maintainer(s). > 7. Things related to people. Such as: > * Who is in charge of a release? Whoever the lead maintainer(s) says is. > * Who may make a good candidate for an RM (release manager)? The one person who volunteers? Sorry, I'm more cynical than you! :) > * I think we need to encourage developers to prioritize bugs during > phase two and/or phase three in the release cycle (see my patches for > the three phases). It will make the quality of the new release > better, or at least give developers an overview of the general > development (bugfix) direction. Obviously we've always tried to do that. Good luck! > * Currently, the version of an RC release (returned by > `(emacs-version)') is the same as a stable release, but as a user, > sometimes I can't tell if I'm using a stable version of Emacs or a > release candidate. I still think something like 25.1-rc1 is better > than 25.1, because it's clearer. The whole point of an RC is that the tarfile is literally identical to the release. If all goes as planned, it IS the release. Therefore it has to have the same version number. Otherwise it's just another pretest. Personally I have never found this a source of confusion. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-11 19:59 ` Glenn Morris @ 2015-11-12 8:53 ` Xue Fuqiao 2015-11-15 2:42 ` Glenn Morris 0 siblings, 1 reply; 765+ messages in thread From: Xue Fuqiao @ 2015-11-12 8:53 UTC (permalink / raw) To: Glenn Morris; +Cc: Eli Zaretskii, nicolas, Emacs-devel On Thu, Nov 12, 2015 at 3:59 AM, Glenn Morris <rgm@gnu.org> wrote: Hi Glenn, > Does the (long-standing) name of the file really make a difference to anything? Hmm... Personally, I think "for release" is just a list of activities that must be completed before the next release, but "release process" or "release cycle" is throughout Emacs development. Since English is not my native language, my feeling could be wrong. > If you are going to rename it, you don't have to stick with an > old-school SHOUTY name, you can use lower-case. OK. I can change it if no one disagrees. >> For example, how to set the bug meta-data for release-critical bugs, >> what meta-data to set, > > In the past we increased the severity of such bugs. > Personally I felt this was a bad idea, > > http://lists.gnu.org/archive/html/emacs-devel/2015-02/msg00196.html > > so I unilaterally started using "block" for this. > That thread explains how it works. > > No one else has shown any interest in tracking such things AFAIK. Perhaps many developers aren't aware of it. (I'm an example.) >> 5. Add information about uploading the Windows binary to >> https://ftp.gnu.org/gnu/emacs/windows/, in `admin/make-tarball.txt'. > > In exactly the same way anything else is uploaded to ftp.gnu.org? Well, I mean _build and upload_ the binary. Maybe Someone™ familiar with Windows should write a script to build a Windows binary for release automatically. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-12 8:53 ` Xue Fuqiao @ 2015-11-15 2:42 ` Glenn Morris 2015-11-16 10:38 ` Juanma Barranquero 2015-11-16 16:54 ` John Wiegley 0 siblings, 2 replies; 765+ messages in thread From: Glenn Morris @ 2015-11-15 2:42 UTC (permalink / raw) To: Xue Fuqiao; +Cc: Eli Zaretskii, nicolas, Emacs-devel Xue Fuqiao wrote: > Hmm... Personally, I think "for release" is just a list of activities > that must be completed before the next release, but "release process" or > "release cycle" is throughout Emacs development. Fair enough. >> No one else has shown any interest in tracking such things AFAIK. > > Perhaps many developers aren't aware of it. (I'm an example.) AFAIK, nobody thought to even ask "how shall we track the bugs we need to fix for the next release". Till now! :) > Well, I mean _build and upload_ the binary. Maybe Someone™ familiar > with Windows should write a script to build a Windows binary for release > automatically. Perhaps. Personally I wouldn't like to see "provide pre-built binaries for MS Windows users" becomes an "official" responsibility of Emacs. It's just something that some people have been doing on a best effort basis. But of course the people who do the work get to make the decisions. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-15 2:42 ` Glenn Morris @ 2015-11-16 10:38 ` Juanma Barranquero 2015-11-16 16:54 ` John Wiegley 1 sibling, 0 replies; 765+ messages in thread From: Juanma Barranquero @ 2015-11-16 10:38 UTC (permalink / raw) To: Glenn Morris; +Cc: Xue Fuqiao, Eli Zaretskii, nicolas, Emacs-devel [-- Attachment #1: Type: text/plain, Size: 767 bytes --] On Sun, Nov 15, 2015 at 3:42 AM, Glenn Morris <rgm@gnu.org> wrote: > Perhaps. Personally I wouldn't like to see "provide pre-built binaries > for MS Windows users" becomes an "official" responsibility of Emacs. > It's just something that some people have been doing on a best effort basis. > But of course the people who do the work get to make the decisions. Which just reminds me... I've been building 32-bit, non-opt, checking-and-debugging-enabled binary snapshots from trunk (and will do now from emacs-25), but as I put then in my Dropbox and I don't want the hassle to have to put source tarballs too, I haven't publicised them at all, just to interested parties. I'd be willing to upload them to some place a bit more "official", if that would be useful. [-- Attachment #2: Type: text/html, Size: 1000 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-15 2:42 ` Glenn Morris 2015-11-16 10:38 ` Juanma Barranquero @ 2015-11-16 16:54 ` John Wiegley 2015-11-18 18:12 ` Glenn Morris 1 sibling, 1 reply; 765+ messages in thread From: John Wiegley @ 2015-11-16 16:54 UTC (permalink / raw) To: Glenn Morris; +Cc: Xue Fuqiao, Eli Zaretskii, nicolas, Emacs-devel >>>>> Glenn Morris <rgm@gnu.org> writes: > AFAIK, nobody thought to even ask "how shall we track the bugs we need to > fix for the next release". Till now! :) I had suggested using a release tag for 25.1 in debbugs. Is that not possible? At some time soon we'll need to start assessing existing bugs and applying that tag to them. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-16 16:54 ` John Wiegley @ 2015-11-18 18:12 ` Glenn Morris 2015-11-18 18:36 ` Glenn Morris 2015-11-18 22:06 ` John Wiegley 0 siblings, 2 replies; 765+ messages in thread From: Glenn Morris @ 2015-11-18 18:12 UTC (permalink / raw) To: Xue Fuqiao; +Cc: Eli Zaretskii, nicolas, Emacs-devel John Wiegley wrote: [I see you use Mail-Followup-To, which results in looking like I'm writing to someone else.] >>>>>> Glenn Morris <rgm@gnu.org> writes: > >> AFAIK, nobody thought to even ask "how shall we track the bugs we need to >> fix for the next release". Till now! :) > > I had suggested using a release tag for 25.1 in debbugs. Is that not > possible? At some time soon we'll need to start assessing existing > bugs and applying that tag to them. I started tracking 25.1 bugs in February, since we've always known the next release is coming, and the regressions and security issues were already piling up. http://debbugs.gnu.org/19759 is my (partial) selection, I don't claim it's exhaustive. You can use a usertag if you prefer, but personally I think block/unblock is better. IMO now is the time to start tracking 25.2 (or whatever master is to be released as) issues as well. The "list of issues that need to be fixed before release" should always be being updated, else it's easy for items to get lost. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-18 18:12 ` Glenn Morris @ 2015-11-18 18:36 ` Glenn Morris 2015-11-18 22:06 ` John Wiegley 1 sibling, 0 replies; 765+ messages in thread From: Glenn Morris @ 2015-11-18 18:36 UTC (permalink / raw) To: Xue Fuqiao; +Cc: Eli Zaretskii, nicolas, Emacs-devel Glenn Morris wrote: > http://debbugs.gnu.org/19759 is my (partial) selection, PS does not include standard tasks (see whatever FOR-RELEASE is called now), like reviewing NEWS and documenting everything that needs it, and proof-reading every chapter of the manual and lispref. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-18 18:12 ` Glenn Morris 2015-11-18 18:36 ` Glenn Morris @ 2015-11-18 22:06 ` John Wiegley 1 sibling, 0 replies; 765+ messages in thread From: John Wiegley @ 2015-11-18 22:06 UTC (permalink / raw) To: Glenn Morris; +Cc: Xue Fuqiao, Eli Zaretskii, nicolas, Emacs-devel >>>>> Glenn Morris <rgm@gnu.org> writes: > [I see you use Mail-Followup-To, which results in looking like I'm > writing to someone else.] What is the proper method to use? > You can use a usertag if you prefer, but personally I think block/unblock is > better. Ok, block/unblock sounds fine. > IMO now is the time to start tracking 25.2 (or whatever master is to be > released as) issues as well. The "list of issues that need to be fixed > before release" should always be being updated, else it's easy for items to > get lost. Agreed. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-10 0:07 ` John Wiegley 2015-11-10 8:41 ` Xue Fuqiao @ 2015-11-10 9:41 ` Nicolas Petton 2015-11-10 14:22 ` John Wiegley 2015-11-10 16:24 ` Eli Zaretskii 1 sibling, 2 replies; 765+ messages in thread From: Nicolas Petton @ 2015-11-10 9:41 UTC (permalink / raw) To: John Wiegley, Xue Fuqiao; +Cc: Eli Zaretskii, Emacs-devel [-- Attachment #1: Type: text/plain, Size: 561 bytes --] John Wiegley <jwiegley@gmail.com> writes: >> Actually, I think we should document our release process more >> explicitly. `admin/FOR-RELEASE' and `admin/notes/versioning' are not >> enough. admin/make-tarball.txt is also very useful. > > I agree. Would you be willing to contribute some drafting? I myself am still > unfamiliar with all of our procedures in this regard. I can take care of building and publishing the various pretest, release candidate and stable tarballs, as well as updating the website for the release, like I did for Emacs 24.5. Nico [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 512 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-10 9:41 ` Nicolas Petton @ 2015-11-10 14:22 ` John Wiegley 2015-11-10 16:38 ` Eli Zaretskii 2015-11-10 17:39 ` Nicolas Petton 2015-11-10 16:24 ` Eli Zaretskii 1 sibling, 2 replies; 765+ messages in thread From: John Wiegley @ 2015-11-10 14:22 UTC (permalink / raw) To: Nicolas Petton; +Cc: Xue Fuqiao, Eli Zaretskii, Emacs-devel >>>>> Nicolas Petton <nicolas@petton.fr> writes: > I can take care of building and publishing the various pretest, release > candidate and stable tarballs, as well as updating the website for the > release, like I did for Emacs 24.5. Thank you, Nicolas! As you do so, can you keep a journal of the exact steps you follow, so I can learn to repeat what you're about to do? John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-10 14:22 ` John Wiegley @ 2015-11-10 16:38 ` Eli Zaretskii 2015-11-10 17:34 ` Nicolas Petton 2015-11-10 17:39 ` Nicolas Petton 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-10 16:38 UTC (permalink / raw) To: John Wiegley; +Cc: xfq.free, nicolas, emacs-devel > From: John Wiegley <jwiegley@gmail.com> > Cc: Xue Fuqiao <xfq.free@gmail.com>, Eli Zaretskii <eliz@gnu.org>, Emacs-devel <emacs-devel@gnu.org> > Date: Tue, 10 Nov 2015 06:22:37 -0800 > > >>>>> Nicolas Petton <nicolas@petton.fr> writes: > > > I can take care of building and publishing the various pretest, release > > candidate and stable tarballs, as well as updating the website for the > > release, like I did for Emacs 24.5. > > Thank you, Nicolas! As you do so, can you keep a journal of the exact steps > you follow, so I can learn to repeat what you're about to do? I think the steps are already documented in admin/make-tarball.txt and admin/FOR-RELEASE. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-10 16:38 ` Eli Zaretskii @ 2015-11-10 17:34 ` Nicolas Petton 0 siblings, 0 replies; 765+ messages in thread From: Nicolas Petton @ 2015-11-10 17:34 UTC (permalink / raw) To: Eli Zaretskii, John Wiegley; +Cc: xfq.free, emacs-devel [-- Attachment #1: Type: text/plain, Size: 477 bytes --] Eli Zaretskii <eliz@gnu.org> writes: >> Thank you, Nicolas! As you do so, can you keep a journal of the exact steps >> you follow, so I can learn to repeat what you're about to do? > > I think the steps are already documented in admin/make-tarball.txt and > admin/FOR-RELEASE. These are exactly the steps I'm following. It's all very well documented. With the initial help of Glenn last time I was able to learned very quickly how to build the tarballs and test them. Nico [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 512 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-10 14:22 ` John Wiegley 2015-11-10 16:38 ` Eli Zaretskii @ 2015-11-10 17:39 ` Nicolas Petton 2015-11-10 18:01 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Nicolas Petton @ 2015-11-10 17:39 UTC (permalink / raw) To: John Wiegley; +Cc: Xue Fuqiao, Eli Zaretskii, Emacs-devel [-- Attachment #1: Type: text/plain, Size: 636 bytes --] John Wiegley <jwiegley@gmail.com> writes: >>>>>> Nicolas Petton <nicolas@petton.fr> writes: > >> I can take care of building and publishing the various pretest, release >> candidate and stable tarballs, as well as updating the website for the >> release, like I did for Emacs 24.5. > > Thank you, Nicolas! You're welcome! > As you do so, can you keep a journal of the exact steps > you follow, so I can learn to repeat what you're about to do? Sure, and as I said it's for the most part already well documented :) BTW, even if we freeze Friday, I guess there won't be a pretest this week? (I will be offline for a few days). Nico [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 512 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-10 17:39 ` Nicolas Petton @ 2015-11-10 18:01 ` Eli Zaretskii 2015-11-11 16:47 ` Nicolas Petton 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-10 18:01 UTC (permalink / raw) To: Nicolas Petton; +Cc: xfq.free, jwiegley, emacs-devel > From: Nicolas Petton <nicolas@petton.fr> > Cc: Xue Fuqiao <xfq.free@gmail.com>, Eli Zaretskii <eliz@gnu.org>, Emacs-devel <emacs-devel@gnu.org> > Date: Tue, 10 Nov 2015 18:39:43 +0100 > > BTW, even if we freeze Friday, I guess there won't be a pretest this > week? (I will be offline for a few days). IMO, the pretest should be tarred something like 2 weeks after either the freeze or the branch, to let people who didn't actively use the master version start using it and fix any grave bugs. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-10 18:01 ` Eli Zaretskii @ 2015-11-11 16:47 ` Nicolas Petton 0 siblings, 0 replies; 765+ messages in thread From: Nicolas Petton @ 2015-11-11 16:47 UTC (permalink / raw) To: Eli Zaretskii; +Cc: xfq.free, jwiegley, emacs-devel [-- Attachment #1: Type: text/plain, Size: 266 bytes --] Eli Zaretskii <eliz@gnu.org> writes: > IMO, the pretest should be tarred something like 2 weeks after either > the freeze or the branch, to let people who didn't actively use the > master version start using it and fix any grave bugs. Ok, that works for me. Nico [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 512 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-10 9:41 ` Nicolas Petton 2015-11-10 14:22 ` John Wiegley @ 2015-11-10 16:24 ` Eli Zaretskii 1 sibling, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-10 16:24 UTC (permalink / raw) To: Nicolas Petton; +Cc: xfq.free, jwiegley, emacs-devel > From: Nicolas Petton <nicolas@petton.fr> > Cc: Eli Zaretskii <eliz@gnu.org>, Emacs-devel <emacs-devel@gnu.org> > Date: Tue, 10 Nov 2015 10:41:56 +0100 > > I can take care of building and publishing the various pretest, release > candidate and stable tarballs, as well as updating the website for the > release, like I did for Emacs 24.5. Thank you! ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-09 21:55 ` Feature freezes and Emacs 25 John Wiegley 2015-11-09 22:08 ` Dmitry Gutov 2015-11-09 23:59 ` Xue Fuqiao @ 2015-11-11 0:17 ` Juri Linkov 2015-11-11 1:16 ` John Wiegley 2015-11-11 1:21 ` Feature freezes and Emacs 25 Drew Adams 2 siblings, 2 replies; 765+ messages in thread From: Juri Linkov @ 2015-11-11 0:17 UTC (permalink / raw) To: emacs-devel >> I think we should first decide whether new features that are "almost ready" >> should or should not be in 25.1. Two examples that immediately come to mind >> are dynamic loading and xwidgets; I don't know if there are others. After we >> make the decision, we could see if one week's time is enough. > > I'd like to see both of those in 25.1. > > Let's freeze this Friday, and take a step back. We have several courses open: > > 1. Decide that what we have now should become 24.6. > > 2. Decide it will become 25.1. > > 3. Decide that we want to bring in more features that aren't yet complete, > and so push the freeze to a future date. John, could you please extend the deadline of the feature freeze a little since I have no chance to commit all changes until Friday. Basically what I'm doing is the same kind of work as Alan's efforts in bug#17453. While Alan is designing a framework to support multiple windows by adding a new arg with a group of windows, I'm designing a framework to support multiple regions by adding a new arg with a group of regions. In bug#19829 I've collected the evidence of commands that need this feature as a basis for the new design, but the deadlock was caused by the same question that backpedaled the Alan's design: whether to add a new arg to the existing functions or to try stuffing it into the existing ones? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-11 0:17 ` Juri Linkov @ 2015-11-11 1:16 ` John Wiegley 2015-11-12 0:43 ` Juri Linkov 2015-11-12 21:38 ` Design of commands operating on rectangular regions (was: Feature freezes and Emacs 25) Juri Linkov 2015-11-11 1:21 ` Feature freezes and Emacs 25 Drew Adams 1 sibling, 2 replies; 765+ messages in thread From: John Wiegley @ 2015-11-11 1:16 UTC (permalink / raw) To: Juri Linkov; +Cc: emacs-devel >>>>> Juri Linkov <juri@linkov.net> writes: > John, could you please extend the deadline of the feature freeze a little > since I have no chance to commit all changes until Friday. > > Basically what I'm doing is the same kind of work as Alan's efforts in > bug#17453. While Alan is designing a framework to support multiple windows > by adding a new arg with a group of windows, I'm designing a framework to > support multiple regions by adding a new arg with a group of regions. > > In bug#19829 I've collected the evidence of commands that need this feature > as a basis for the new design, but the deadlock was caused by the same > question that backpedaled the Alan's design: whether to add a new arg to the > existing functions or to try stuffing it into the existing ones? Given the discussion Alan and I are having, maybe we should step back the three of us and make sure that we're taking a consistent approach. If your work is similar to Alan's in nature, I'd be willing to extend its deadline beyond the freeze date as well -- if it doesn't come in too late. I'd rather not extend the freeze overall, since otherwise we might keep doing it. Too many cool ideas out there. :) The freeze is motivation to get 25.1 out the door, so 25.2 can come sooner. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-11 1:16 ` John Wiegley @ 2015-11-12 0:43 ` Juri Linkov 2015-11-12 1:05 ` John Wiegley 2015-11-12 4:01 ` Artur Malabarba 2015-11-12 21:38 ` Design of commands operating on rectangular regions (was: Feature freezes and Emacs 25) Juri Linkov 1 sibling, 2 replies; 765+ messages in thread From: Juri Linkov @ 2015-11-12 0:43 UTC (permalink / raw) To: emacs-devel >> John, could you please extend the deadline of the feature freeze a little >> since I have no chance to commit all changes until Friday. >> >> Basically what I'm doing is the same kind of work as Alan's efforts in >> bug#17453. While Alan is designing a framework to support multiple windows >> by adding a new arg with a group of windows, I'm designing a framework to >> support multiple regions by adding a new arg with a group of regions. >> >> In bug#19829 I've collected the evidence of commands that need this feature >> as a basis for the new design, but the deadlock was caused by the same >> question that backpedaled the Alan's design: whether to add a new arg to the >> existing functions or to try stuffing it into the existing ones? > > Given the discussion Alan and I are having, maybe we should step back the > three of us and make sure that we're taking a consistent approach. > > If your work is similar to Alan's in nature, I'd be willing to extend its > deadline beyond the freeze date as well -- if it doesn't come in too late. I'd > rather not extend the freeze overall, since otherwise we might keep doing it. > Too many cool ideas out there. :) > > The freeze is motivation to get 25.1 out the door, so 25.2 can come sooner. Actually I'm happy that you are pushing for the sooner release, so now we have to concentrate on both these almost finished features. Also in the next release I'd like to see improvements in the Isearch prompt listed in the proposal Artur published on EmacsWiki, but it seems it's impossible to reach consensus in a reasonable time before the next release due to a wide spectrum of opinions, so perhaps Isearch prompt changes need to wait for 25.2. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-12 0:43 ` Juri Linkov @ 2015-11-12 1:05 ` John Wiegley 2015-11-12 4:01 ` Artur Malabarba 1 sibling, 0 replies; 765+ messages in thread From: John Wiegley @ 2015-11-12 1:05 UTC (permalink / raw) To: Juri Linkov; +Cc: emacs-devel >>>>> Juri Linkov <juri@linkov.net> writes: > Also in the next release I'd like to see improvements in the Isearch prompt > listed in the proposal Artur published on EmacsWiki, but it seems it's > impossible to reach consensus in a reasonable time before the next release > due to a wide spectrum of opinions, so perhaps Isearch prompt changes need > to wait for 25.2. I agree. 25.2 won't be that long after 25.1, so this shouldn't sound like a kiss of death. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-12 0:43 ` Juri Linkov 2015-11-12 1:05 ` John Wiegley @ 2015-11-12 4:01 ` Artur Malabarba 2015-11-12 16:48 ` John Wiegley 2015-11-12 17:33 ` Eli Zaretskii 1 sibling, 2 replies; 765+ messages in thread From: Artur Malabarba @ 2015-11-12 4:01 UTC (permalink / raw) To: Juri Linkov; +Cc: emacs-devel Juri Linkov <juri@linkov.net> writes: > Actually I'm happy that you are pushing for the sooner release, > so now we have to concentrate on both these almost finished features. > > Also in the next release I'd like to see improvements in the Isearch prompt > listed in the proposal Artur published on EmacsWiki, but it seems it's > impossible to reach consensus in a reasonable time before the next release > due to a wide spectrum of opinions, so perhaps Isearch prompt changes need > to wait for 25.2. Even if we did postpone the feature-freeze, I'd probably still not apply the isearch patch until after that. Call me a buzzkill, but I actually like to know that “sensitive” features are going to get a good amount of testing before being called “stable”. 😄 That's twice as valid when the code involves some decisions that we're going to have to live with afterwards (yes window*-start, I'm looking at you 😉). ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-12 4:01 ` Artur Malabarba @ 2015-11-12 16:48 ` John Wiegley 2015-11-12 17:33 ` Eli Zaretskii 1 sibling, 0 replies; 765+ messages in thread From: John Wiegley @ 2015-11-12 16:48 UTC (permalink / raw) To: Artur Malabarba; +Cc: emacs-devel, Juri Linkov >>>>> Artur Malabarba <bruce.connor.am@gmail.com> writes: > Call me a buzzkill, but I actually like to know that “sensitive” features > are going to get a good amount of testing before being called “stable”. 😄 If it's something you care about, consider that motivation to do more testing during the pre-release cycle. :) Whatever feature is introduced, until it is released the only ones who will test it are the developers building from Emacs.git. A pre-release tarball actually has a much larger audience. And we always have the option of backing out the change if it receives too much bad feedback. > That's twice as valid when the code involves some decisions that we're going > to have to live with afterwards (yes window*-start, I'm looking at you 😉). Agreed. When it comes to modifying core functionality, we need to proceed very cautiously. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-12 4:01 ` Artur Malabarba 2015-11-12 16:48 ` John Wiegley @ 2015-11-12 17:33 ` Eli Zaretskii 2015-11-12 19:01 ` Artur Malabarba 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-12 17:33 UTC (permalink / raw) To: Artur Malabarba; +Cc: emacs-devel, juri > From: Artur Malabarba <bruce.connor.am@gmail.com> > Date: Thu, 12 Nov 2015 04:01:29 +0000 > Cc: emacs-devel@gnu.org > > > Also in the next release I'd like to see improvements in the Isearch prompt > > listed in the proposal Artur published on EmacsWiki, but it seems it's > > impossible to reach consensus in a reasonable time before the next release > > due to a wide spectrum of opinions, so perhaps Isearch prompt changes need > > to wait for 25.2. > > Even if we did postpone the feature-freeze, I'd probably still not apply > the isearch patch until after that. > Call me a buzzkill, but I actually like to know that “sensitive” > features are going to get a good amount of testing before being called > “stable”. 😄 > > That's twice as valid when the code involves some decisions that we're > going to have to live with afterwards (yes window*-start, I'm looking at > you 😉). These are all valid considerations, but we should take them in their correct perspective: with the release some 8 months away (according to the previous statistics), we have enough time to make sure it's stable. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-12 17:33 ` Eli Zaretskii @ 2015-11-12 19:01 ` Artur Malabarba 2015-11-15 1:51 ` Xue Fuqiao 0 siblings, 1 reply; 765+ messages in thread From: Artur Malabarba @ 2015-11-12 19:01 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Juri Linkov, emacs-devel [-- Attachment #1: Type: text/plain, Size: 547 bytes --] > > From: Artur Malabarba <bruce.connor.am@gmail.com> > > Even if we did postpone the feature-freeze, I'd probably still not apply > > the isearch patch until after that. > > Call me a buzzkill, but I actually like to know that “sensitive” > > features are going to get a good amount of testing before being called > > “stable”. 😄 Actually, this came out a bit wrong. I meant to say "the sensitive features that I write". As in, it makes me feel safer. I didn't mean to imply that other people are doing anything wrong here. [-- Attachment #2: Type: text/html, Size: 711 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-12 19:01 ` Artur Malabarba @ 2015-11-15 1:51 ` Xue Fuqiao 2015-11-16 16:12 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Xue Fuqiao @ 2015-11-15 1:51 UTC (permalink / raw) To: emacs-devel [-- Attachment #1: Type: text/plain, Size: 194 bytes --] Hi, I've changed RELEASE-PROCESS to lower-case and removed the feature freeze section of my patches. I'll push it to `master' later. It can be tweaked in the repository afterwards if needed. [-- Attachment #2: Type: text/html, Size: 333 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-15 1:51 ` Xue Fuqiao @ 2015-11-16 16:12 ` Eli Zaretskii 2015-11-16 23:59 ` Xue Fuqiao 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-16 16:12 UTC (permalink / raw) To: Xue Fuqiao; +Cc: emacs-devel > Date: Sun, 15 Nov 2015 09:51:40 +0800 > From: Xue Fuqiao <xfq.free@gmail.com> > > I've changed RELEASE-PROCESS to lower-case and removed the feature > freeze section of my patches. I'll push it to `master' later. Thanks, but why to 'master'? Doesn't the document describe the process we want to use during the release of Emacs 25.1? If so, then its place is on the emacs-25 branch, and since this is documentation that cannot possibly break anything, there are no dilemmas regarding its effect on stability. I thought I wrote a day or two ago that documentation changes should go to emacs-25, not to master. (Actually, the default branch for pushing any work should now be emacs-25, except for new features.) TIA ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-16 16:12 ` Eli Zaretskii @ 2015-11-16 23:59 ` Xue Fuqiao 2015-11-17 3:43 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Xue Fuqiao @ 2015-11-16 23:59 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Emacs-devel On Tue, Nov 17, 2015 at 12:12 AM, Eli Zaretskii <eliz@gnu.org> wrote: >> Date: Sun, 15 Nov 2015 09:51:40 +0800 >> From: Xue Fuqiao <xfq.free@gmail.com> >> >> I've changed RELEASE-PROCESS to lower-case and removed the feature >> freeze section of my patches. I'll push it to `master' later. > > Thanks, but why to 'master'? Doesn't the document describe the > process we want to use during the release of Emacs 25.1? If so, then > its place is on the emacs-25 branch, and since this is documentation > that cannot possibly break anything, there are no dilemmas regarding > its effect on stability. Mea culpa. I remembered that the admin/ directory was not in the release tarball, but I just found that I was wrong (it _is_ in my Emacs 24.5 tarball). And yes, I'll push my not-new-feature commits to the "emacs-25" branch before the 25.1 release. What should I do now? Cherry-pick my commits and add “Backport:” to the commit log? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-16 23:59 ` Xue Fuqiao @ 2015-11-17 3:43 ` Eli Zaretskii 2015-11-18 0:47 ` Xue Fuqiao 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-17 3:43 UTC (permalink / raw) To: Xue Fuqiao; +Cc: emacs-devel > Date: Tue, 17 Nov 2015 07:59:57 +0800 > From: Xue Fuqiao <xfq.free@gmail.com> > Cc: Emacs-devel <emacs-devel@gnu.org> > > > Thanks, but why to 'master'? Doesn't the document describe the > > process we want to use during the release of Emacs 25.1? If so, then > > its place is on the emacs-25 branch, and since this is documentation > > that cannot possibly break anything, there are no dilemmas regarding > > its effect on stability. > > Mea culpa. No sweat. > I remembered that the admin/ directory was not in the release tarball, > but I just found that I was wrong (it _is_ in my Emacs 24.5 tarball). That shouldn't be a factor. > What should I do now? Cherry-pick my commits and add “Backport:” to the > commit log? Yes, please. Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-17 3:43 ` Eli Zaretskii @ 2015-11-18 0:47 ` Xue Fuqiao 0 siblings, 0 replies; 765+ messages in thread From: Xue Fuqiao @ 2015-11-18 0:47 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Emacs-devel On Tue, Nov 17, 2015 at 11:43 AM, Eli Zaretskii <eliz@gnu.org> wrote: >> What should I do now? Cherry-pick my commits and add “Backport:” to the >> commit log? > > Yes, please. Done. Thank you. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Design of commands operating on rectangular regions (was: Feature freezes and Emacs 25) 2015-11-11 1:16 ` John Wiegley 2015-11-12 0:43 ` Juri Linkov @ 2015-11-12 21:38 ` Juri Linkov 2015-11-20 19:10 ` Design of commands operating on rectangular regions John Wiegley 1 sibling, 1 reply; 765+ messages in thread From: Juri Linkov @ 2015-11-12 21:38 UTC (permalink / raw) To: emacs-devel [-- Attachment #1: Type: text/plain, Size: 221 bytes --] > If your work is similar to Alan's in nature, I'd be willing to extend its > deadline beyond the freeze date as well -- if it doesn't come in too late. Thanks, here is a complete patch from bug#19829 ready to install: [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: rectangular_regions.patch --] [-- Type: text/x-diff, Size: 18390 bytes --] diff --git a/lisp/simple.el b/lisp/simple.el index 1f2f4fe..3d09a54 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -970,15 +970,34 @@ (defcustom delete-active-region t (defvar region-extract-function (lambda (delete) (when (region-beginning) - (if (eq delete 'delete-only) - (delete-region (region-beginning) (region-end)) - (filter-buffer-substring (region-beginning) (region-end) delete)))) + (cond + ((eq delete 'bounds) + (list (cons (region-beginning) (region-end)))) + ((eq delete 'delete-only) + (delete-region (region-beginning) (region-end))) + (t + (filter-buffer-substring (region-beginning) (region-end) delete))))) "Function to get the region's content. Called with one argument DELETE. If DELETE is `delete-only', then only delete the region and the return value is undefined. If DELETE is nil, just return the content as a string. +If DELETE is `bounds', then don't delete, but just return the +bounds of the region as a list of (START . END) boundaries. If anything else, delete the region and return its content as a string.") +(defvar region-insert-function + (lambda (lines) + (let ((first t)) + (while lines + (or first + (insert ?\n)) + (insert-for-yank (car lines)) + (setq lines (cdr lines) + first nil)))) + "Function to insert the region's content. +Called with one argument LINES. +Insert the region as a list of lines.") + (defun delete-backward-char (n &optional killflag) "Delete the previous N characters (following if N is negative). If Transient Mark mode is enabled, the mark is active, and N is 1, @@ -3282,7 +3306,8 @@ (defun shell-command-sentinel (process signal) (defun shell-command-on-region (start end command &optional output-buffer replace - error-buffer display-error-buffer) + error-buffer display-error-buffer + region-noncontiguous-p) "Execute string COMMAND in inferior shell with region as input. Normally display output (if any) in temp buffer `*Shell Command Output*'; Prefix arg means replace the region with it. Return the exit code of @@ -3345,7 +3370,8 @@ (defun shell-command-on-region (start end command current-prefix-arg current-prefix-arg shell-command-default-error-buffer - t))) + t + (region-noncontiguous-p)))) (let ((error-file (if error-buffer (make-temp-file @@ -3354,6 +3380,19 @@ (defun shell-command-on-region (start end command temporary-file-directory))) nil)) exit-status) + ;; Unless a single contiguous chunk is selected, operate on multiple chunks. + (if region-noncontiguous-p + (let ((input (concat (funcall region-extract-function 'delete) "\n")) + output) + (with-temp-buffer + (insert input) + (call-process-region (point-min) (point-max) + shell-file-name t t + nil shell-command-switch + command) + (setq output (split-string (buffer-string) "\n"))) + (goto-char start) + (funcall region-insert-function output)) (if (or replace (and output-buffer (not (or (bufferp output-buffer) (stringp output-buffer))))) @@ -3443,7 +3482,7 @@ (defun shell-command-on-region (start end command exit-status output)))) ;; Don't kill: there might be useful info in the undo-log. ;; (kill-buffer buffer) - )))) + ))))) (when (and error-file (file-exists-p error-file)) (if (< 0 (nth 7 (file-attributes error-file))) @@ -5038,6 +5077,8 @@ (defun region-active-p () ;; region is active when there's no mark. (progn (cl-assert (mark)) t))) +(defun region-noncontiguous-p () + (> (length (funcall region-extract-function 'bounds)) 1)) (defvar redisplay-unhighlight-region-function (lambda (rol) (when (overlayp rol) (delete-overlay rol)))) diff --git a/lisp/rect.el b/lisp/rect.el index acd3a48..560fbc2 100644 --- a/lisp/rect.el +++ b/lisp/rect.el @@ -257,6 +257,19 @@ (defun extract-rectangle (start end) (apply-on-rectangle 'extract-rectangle-line start end lines) (nreverse (cdr lines)))) +(defun extract-rectangle-bounds (start end) + "Return the bounds of the rectangle with corners at START and END. +Return it as a list of (START . END) boundaries, one for each line of +the rectangle." + (let (bounds) + (apply-on-rectangle + (lambda (startcol endcol) + (move-to-column startcol) + (push (cons (prog1 (point) (move-to-column endcol)) (point)) + bounds)) + start end) + (nreverse bounds))) + (defvar killed-rectangle nil "Rectangle for `yank-rectangle' to insert.") @@ -563,6 +576,8 @@ (add-function :around redisplay-unhighlight-region-function #'rectangle--unhighlight-for-redisplay) (add-function :around region-extract-function #'rectangle--extract-region) +(add-function :around region-insert-function + #'rectangle--insert-region) (defvar rectangle-mark-mode-map (let ((map (make-sparse-keymap))) @@ -681,8 +696,12 @@ (defun rectangle-previous-line (&optional n) (defun rectangle--extract-region (orig &optional delete) - (if (not rectangle-mark-mode) - (funcall orig delete) + (cond + ((not rectangle-mark-mode) + (funcall orig delete)) + ((eq delete 'bounds) + (extract-rectangle-bounds (region-beginning) (region-end))) + (t (let* ((strs (funcall (if delete #'delete-extract-rectangle #'extract-rectangle) @@ -696,7 +715,14 @@ (defun rectangle--extract-region (orig &optional delete) (put-text-property 0 (length str) 'yank-handler `(rectangle--insert-for-yank ,strs t) str) - str)))) + str))))) + +(defun rectangle--insert-region (orig strings) + (cond + ((not rectangle-mark-mode) + (funcall orig strings)) + (t + (funcall #'insert-rectangle strings)))) (defun rectangle--insert-for-yank (strs) (push (point) buffer-undo-list) diff --git a/lisp/emulation/cua-rect.el b/lisp/emulation/cua-rect.el index ea8b524..d389f6e 100644 --- a/lisp/emulation/cua-rect.el +++ b/lisp/emulation/cua-rect.el @@ -666,6 +666,22 @@ (defun cua--extract-rectangle () (setq rect (cons row rect)))))) (nreverse rect))) +(defun cua--extract-rectangle-bounds () + (let (rect) + (if (not (cua--rectangle-virtual-edges)) + (cua--rectangle-operation nil nil nil nil nil ; do not tabify + (lambda (s e _l _r) + (setq rect (cons (cons s e) rect)))) + (cua--rectangle-operation nil 1 nil nil nil ; do not tabify + (lambda (s e l r _v) + (goto-char s) + (move-to-column l) + (setq s (point)) + (move-to-column r) + (setq e (point)) + (setq rect (cons (cons s e) rect))))) + (nreverse rect))) + (defun cua--insert-rectangle (rect &optional below paste-column line-count) ;; Insert rectangle as insert-rectangle, but don't set mark and exit with ;; point at either next to top right or below bottom left corner @@ -1394,6 +1410,8 @@ (defun cua--rectangle-post-command () (add-function :around region-extract-function #'cua--rectangle-region-extract) +(add-function :around region-insert-function + #'cua--insert-rectangle) (add-function :around redisplay-highlight-region-function #'cua--rectangle-highlight-for-redisplay) @@ -1405,8 +1423,12 @@ (defun cua--rectangle-highlight-for-redisplay (orig &rest args) (defun cua--rectangle-region-extract (orig &optional delete) (cond - ((not cua--rectangle) (funcall orig delete)) - ((eq delete 'delete-only) (cua--delete-rectangle)) + ((not cua--rectangle) + (funcall orig delete)) + ((eq delete 'bounds) + (cua--extract-rectangle-bounds)) + ((eq delete 'delete-only) + (cua--delete-rectangle)) (t (let* ((strs (cua--extract-rectangle)) (str (mapconcat #'identity strs "\n"))) diff --git a/lisp/replace.el b/lisp/replace.el index d6590c5..a06e363 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -284,7 +284,7 @@ (defun query-replace-read-args (prompt regexp-flag &optional noerror) (and current-prefix-arg (not (eq current-prefix-arg '-))) (and current-prefix-arg (eq current-prefix-arg '-))))) -(defun query-replace (from-string to-string &optional delimited start end backward) +(defun query-replace (from-string to-string &optional delimited start end backward region-noncontiguous-p) "Replace some occurrences of FROM-STRING with TO-STRING. As each match is found, the user must type a character saying what to do with it. For directions, type \\[help-command] at that time. @@ -328,22 +328,21 @@ (defun query-replace (from-string to-string &optional delimited start end backwa (if current-prefix-arg (if (eq current-prefix-arg '-) " backward" " word") "") - (if (and transient-mark-mode mark-active) " in region" "")) + (if (use-region-p) " in region" "")) nil))) (list (nth 0 common) (nth 1 common) (nth 2 common) ;; These are done separately here ;; so that command-history will record these expressions ;; rather than the values they had this time. - (if (and transient-mark-mode mark-active) - (region-beginning)) - (if (and transient-mark-mode mark-active) - (region-end)) - (nth 3 common)))) - (perform-replace from-string to-string t nil delimited nil nil start end backward)) + (if (use-region-p) (region-beginning)) + (if (use-region-p) (region-end)) + (nth 3 common) + (if (use-region-p) (region-noncontiguous-p))))) + (perform-replace from-string to-string t nil delimited nil nil start end backward region-noncontiguous-p)) (define-key esc-map "%" 'query-replace) -(defun query-replace-regexp (regexp to-string &optional delimited start end backward) +(defun query-replace-regexp (regexp to-string &optional delimited start end backward region-noncontiguous-p) "Replace some things after point matching REGEXP with TO-STRING. As each match is found, the user must type a character saying what to do with it. For directions, type \\[help-command] at that time. @@ -408,18 +407,17 @@ (defun query-replace-regexp (regexp to-string &optional delimited start end back (if (eq current-prefix-arg '-) " backward" " word") "") " regexp" - (if (and transient-mark-mode mark-active) " in region" "")) + (if (use-region-p) " in region" "")) t))) (list (nth 0 common) (nth 1 common) (nth 2 common) ;; These are done separately here ;; so that command-history will record these expressions ;; rather than the values they had this time. - (if (and transient-mark-mode mark-active) - (region-beginning)) - (if (and transient-mark-mode mark-active) - (region-end)) - (nth 3 common)))) - (perform-replace regexp to-string t t delimited nil nil start end backward)) + (if (use-region-p) (region-beginning)) + (if (use-region-p) (region-end)) + (nth 3 common) + (if (use-region-p) (region-noncontiguous-p))))) + (perform-replace regexp to-string t t delimited nil nil start end backward region-noncontiguous-p)) (define-key esc-map [?\C-%] 'query-replace-regexp) @@ -485,9 +483,9 @@ (defun query-replace-regexp-eval (regexp to-expr &optional delimited start end) ;; and the user might enter a single token. (replace-match-string-symbols to) (list from (car to) current-prefix-arg - (if (and transient-mark-mode mark-active) + (if (use-region-p) (region-beginning)) - (if (and transient-mark-mode mark-active) + (if (use-region-p) (region-end)))))) (perform-replace regexp (cons 'replace-eval-replacement to-expr) t 'literal delimited nil nil start end)) @@ -523,9 +521,9 @@ (defun map-query-replace-regexp (regexp to-strings &optional n start end) (list from to (and current-prefix-arg (prefix-numeric-value current-prefix-arg)) - (if (and transient-mark-mode mark-active) + (if (use-region-p) (region-beginning)) - (if (and transient-mark-mode mark-active) + (if (use-region-p) (region-end))))) (let (replacements) (if (listp to-strings) @@ -587,12 +585,12 @@ (defun replace-string (from-string to-string &optional delimited start end backw (if (eq current-prefix-arg '-) " backward" " word") "") " string" - (if (and transient-mark-mode mark-active) " in region" "")) + (if (use-region-p) " in region" "")) nil))) (list (nth 0 common) (nth 1 common) (nth 2 common) - (if (and transient-mark-mode mark-active) + (if (use-region-p) (region-beginning)) - (if (and transient-mark-mode mark-active) + (if (use-region-p) (region-end)) (nth 3 common)))) (perform-replace from-string to-string nil nil delimited nil nil start end backward)) @@ -661,12 +659,12 @@ (defun replace-regexp (regexp to-string &optional delimited start end backward) (if (eq current-prefix-arg '-) " backward" " word") "") " regexp" - (if (and transient-mark-mode mark-active) " in region" "")) + (if (use-region-p) " in region" "")) t))) (list (nth 0 common) (nth 1 common) (nth 2 common) - (if (and transient-mark-mode mark-active) + (if (use-region-p) (region-beginning)) - (if (and transient-mark-mode mark-active) + (if (use-region-p) (region-end)) (nth 3 common)))) (perform-replace regexp to-string nil t delimited nil nil start end backward)) @@ -832,7 +830,7 @@ (defun keep-lines (regexp &optional rstart rend interactive) (unless (or (bolp) (eobp)) (forward-line 0)) (point-marker))))) - (if (and interactive transient-mark-mode mark-active) + (if (and interactive (use-region-p)) (setq rstart (region-beginning) rend (progn (goto-char (region-end)) @@ -901,7 +899,7 @@ (defun flush-lines (regexp &optional rstart rend interactive) (progn (goto-char (min rstart rend)) (setq rend (copy-marker (max rstart rend)))) - (if (and interactive transient-mark-mode mark-active) + (if (and interactive (use-region-p)) (setq rstart (region-beginning) rend (copy-marker (region-end))) (setq rstart (point) @@ -951,7 +949,7 @@ (defun how-many (regexp &optional rstart rend interactive) (setq rend (max rstart rend))) (goto-char rstart) (setq rend (point-max))) - (if (and interactive transient-mark-mode mark-active) + (if (and interactive (use-region-p)) (setq rstart (region-beginning) rend (region-end)) (setq rstart (point) @@ -2068,7 +2066,7 @@ (defun replace-dehighlight () (defun perform-replace (from-string replacements query-flag regexp-flag delimited-flag - &optional repeat-count map start end backward) + &optional repeat-count map start end backward region-noncontiguous-p) "Subroutine of `query-replace'. Its complexity handles interactive queries. Don't use this in your own program unless you want to query and set the mark just as `query-replace' does. Instead, write a simple loop like this: @@ -2115,6 +2113,9 @@ (defun perform-replace (from-string replacements ;; If non-nil, it is marker saying where in the buffer to stop. (limit nil) + ;; Use local binding in add-function below. + (isearch-filter-predicate isearch-filter-predicate) + (region-bounds nil) ;; Data for the next match. If a cons, it has the same format as ;; (match-data); otherwise it is t if a match is possible at point. @@ -2127,6 +2128,24 @@ (defun perform-replace (from-string replacements "Query replacing %s with %s: (\\<query-replace-map>\\[help] for help) ") minibuffer-prompt-properties)))) + ;; Unless a single contiguous chunk is selected, operate on multiple chunks. + (when region-noncontiguous-p + (setq region-bounds + (mapcar (lambda (position) + (cons (copy-marker (car position)) + (copy-marker (cdr position)))) + (funcall region-extract-function 'bounds))) + (add-function :after-while isearch-filter-predicate + (lambda (start end) + (delq nil (mapcar + (lambda (bounds) + (and + (>= start (car bounds)) + (<= start (cdr bounds)) + (>= end (car bounds)) + (<= end (cdr bounds)))) + region-bounds))))) + ;; If region is active, in Transient Mark mode, operate on region. (if backward (when end diff --git a/src/casefiddle.c b/src/casefiddle.c index b94ea8e..7064d9d 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c @@ -306,14 +306,30 @@ return Qnil; } -DEFUN ("downcase-region", Fdowncase_region, Sdowncase_region, 2, 2, "r", +DEFUN ("downcase-region", Fdowncase_region, Sdowncase_region, 2, 3, + "(list (region-beginning) (region-end) (region-noncontiguous-p))", doc: /* Convert the region to lower case. In programs, wants two arguments. These arguments specify the starting and ending character numbers of the region to operate on. When used as a command, the text between point and the mark is operated on. */) - (Lisp_Object beg, Lisp_Object end) + (Lisp_Object beg, Lisp_Object end, Lisp_Object region_noncontiguous_p) { - casify_region (CASE_DOWN, beg, end); + Lisp_Object bounds = Qnil; + + if (!NILP (region_noncontiguous_p)) + { + bounds = call1 (Fsymbol_value (intern ("region-extract-function")), + intern ("bounds")); + + while (CONSP (bounds)) + { + casify_region (CASE_DOWN, XCAR (XCAR (bounds)), XCDR (XCAR (bounds))); + bounds = XCDR (bounds); + } + } + else + casify_region (CASE_DOWN, beg, end); + return Qnil; } ^ permalink raw reply related [flat|nested] 765+ messages in thread
* Re: Design of commands operating on rectangular regions 2015-11-12 21:38 ` Design of commands operating on rectangular regions (was: Feature freezes and Emacs 25) Juri Linkov @ 2015-11-20 19:10 ` John Wiegley 2015-11-20 19:19 ` Drew Adams 2015-11-22 23:57 ` Juri Linkov 0 siblings, 2 replies; 765+ messages in thread From: John Wiegley @ 2015-11-20 19:10 UTC (permalink / raw) To: Juri Linkov; +Cc: emacs-devel >>>>> Juri Linkov <juri@linkov.net> writes: > (defun shell-command-on-region (start end command > &optional output-buffer replace > - error-buffer display-error-buffer) > + error-buffer display-error-buffer > + region-noncontiguous-p) > "Execute string COMMAND in inferior shell with region as input. Juri, Can you tell me more about the meaning of `region-noncontiguous-p' here? How does the caller know when this option is required? My takeaway is that this patch conflates user-level indications (selected regions) too closely with the programmatically provided entities (the region specified by START END). Perhaps it points to the need for an `interactive' specifier to request "the current region, though if multiple sub-regions exist, the set of spans indicated by those sub-regions". A function like `shell-command-on-region' should be determined by its arguments. This patch introduces a much tighter coupling with its context of use than what we had previously. To make that last statement clearer: Right now, `shell-command-on-region' acts on a buffer, and a region of text within that buffer. This region is provided to the command through its arguments by (interactive "r"). The only thing that `shell-command-on-region' needs to do beyond that is to query the current buffer, in order to feed text to the executed process. So, our "context" is the current buffer, while everything else is provided by its arguments. Your patch introduces a more hybridized behavior: (interactive "r") provides the total extent of the region, but now there's an additional parameter, `region-noncontiguous-p', that alters the behavior of shell-command-on-region so that it pays attention not only to the current buffer, but also to user-specified regions when drawing text from the buffer. And these regions are only somewhat related to the region provided by "interactive 'r'". I feel that the semantic "level" of these three arguments -- START, END and REGION-NONCONTIGUOUS-P -- are now different, which I find confusing. `region-noncontiguous-p' doesn't relate to the `interactive' form at all, but rather solely to this new behavior, internal to shell-command-on-region. I'd really like to solve this in a different manner for 25.1. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* RE: Design of commands operating on rectangular regions 2015-11-20 19:10 ` Design of commands operating on rectangular regions John Wiegley @ 2015-11-20 19:19 ` Drew Adams 2015-11-23 0:07 ` Juri Linkov 2015-11-22 23:57 ` Juri Linkov 1 sibling, 1 reply; 765+ messages in thread From: Drew Adams @ 2015-11-20 19:19 UTC (permalink / raw) To: John Wiegley, Juri Linkov; +Cc: emacs-devel In order to follow all of this, especially since you now seem to be talking about user-level changes, could someone please specify (describe) the non-contiguous region feature, including how users can create and modify such a region interactively? That would be really helpful, for me at least. And could you specify clearly the relation between this non-contiguous region feature and rectangles? Presumably the former is more general but also allows some handling of rectangles (?). It sounds like there has been a fair amount of implementation already, without really any discussion of the design and how users are affected (interactive behavior - wherever). But let me know if I'm mistaken and am jumping the gun, here. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Design of commands operating on rectangular regions 2015-11-20 19:19 ` Drew Adams @ 2015-11-23 0:07 ` Juri Linkov 2015-11-23 1:53 ` Drew Adams 0 siblings, 1 reply; 765+ messages in thread From: Juri Linkov @ 2015-11-23 0:07 UTC (permalink / raw) To: Drew Adams; +Cc: emacs-devel > In order to follow all of this, especially since you now > seem to be talking about user-level changes, could someone > please specify (describe) the non-contiguous region feature, > including how users can create and modify such a region > interactively? First you can select the non-contiguous region with 'C-x SPC', then extend it with the usual point motion keys, then run one of the commands supporting such regions, e.g. 'C-x C-l' to downcase, 'M-%' to replace occurrences, 'C-u M-|' to replace the region with the command output. > And could you specify clearly the relation between this > non-contiguous region feature and rectangles? Presumably > the former is more general but also allows some handling > of rectangles (?). Rectangles are a subset of non-contiguous regions that can be expanded with other shapes, e.g. circular regions. ^ permalink raw reply [flat|nested] 765+ messages in thread
* RE: Design of commands operating on rectangular regions 2015-11-23 0:07 ` Juri Linkov @ 2015-11-23 1:53 ` Drew Adams 0 siblings, 0 replies; 765+ messages in thread From: Drew Adams @ 2015-11-23 1:53 UTC (permalink / raw) To: Juri Linkov; +Cc: emacs-devel > > In order to follow all of this, especially since you now > > seem to be talking about user-level changes, could someone > > please specify (describe) the non-contiguous region feature, > > including how users can create and modify such a region > > interactively? Thanks for describing it. I don't want to belabor this, but if you have the time, here are some questions. If not, I'll see it when I use it. ;-) > First you can select the non-contiguous region with > 'C-x SPC', then extend it with the usual point motion keys, A non-contiguous region with N pieces has 2*N ends. Which end(s) get extended with the motion keys? And does `C-x SPC' do what it does now, i.e., set a mark at point, so that point is one end of at least one of the pieces? Can the pieces (zones) overlap? > then run one of the commands supporting such regions, e.g. > 'C-x C-l' to downcase, 'M-%' to replace occurrences, 'C-u M-|' > to replace the region with the command output. > > > And could you specify clearly the relation between this > > non-contiguous region feature and rectangles? Presumably > > the former is more general but also allows some handling > > of rectangles (?). > > Rectangles are a subset of non-contiguous regions that can be > expanded with other shapes, e.g. circular regions. OK, so I guess from another post by you that the non-contig region info includes two properties/components: (1) a shape, specifying, e.g., whether the zones form one or more rectangles (or circles or whatever) and (2) the zone limits. Is that right? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Design of commands operating on rectangular regions 2015-11-20 19:10 ` Design of commands operating on rectangular regions John Wiegley 2015-11-20 19:19 ` Drew Adams @ 2015-11-22 23:57 ` Juri Linkov 1 sibling, 0 replies; 765+ messages in thread From: Juri Linkov @ 2015-11-22 23:57 UTC (permalink / raw) To: emacs-devel > Can you tell me more about the meaning of `region-noncontiguous-p' here? > How does the caller know when this option is required? To be able to process a non-contiguous region differently than the ordinary region, a command needs to know either whether it's operating on the special region (so the command itself can acquire all additional information about the region and its shape), or receive all this information through its arg. I provided the patches for both variants in bug#19829, and it seems that you prefer the latter, if I'm not mistaken. Please confirm do you think that it would be better to add a 'region' arg such that when used programmatically it's required to be in this form, or when used interactively it takes a form with fine-grained boundaries: (region (shape . rectangle) (positions . (1 . 2) (3 . 4) (5 . 6) ...) ... to accompany coarse-grained boundaries in START and END args. > My takeaway is that this patch conflates user-level indications (selected > regions) too closely with the programmatically provided entities (the region > specified by START END). Perhaps it points to the need for an `interactive' > specifier to request "the current region, though if multiple sub-regions > exist, the set of spans indicated by those sub-regions". A function like > `shell-command-on-region' should be determined by its arguments. This patch > introduces a much tighter coupling with its context of use than what we had > previously. > > To make that last statement clearer: Right now, `shell-command-on-region' acts > on a buffer, and a region of text within that buffer. This region is provided > to the command through its arguments by (interactive "r"). The only thing that > `shell-command-on-region' needs to do beyond that is to query the current > buffer, in order to feed text to the executed process. So, our "context" is > the current buffer, while everything else is provided by its arguments. > > Your patch introduces a more hybridized behavior: (interactive "r") provides > the total extent of the region, but now there's an additional parameter, > `region-noncontiguous-p', that alters the behavior of shell-command-on-region > so that it pays attention not only to the current buffer, but also to > user-specified regions when drawing text from the buffer. And these regions > are only somewhat related to the region provided by "interactive 'r'". > > I feel that the semantic "level" of these three arguments -- START, END and > REGION-NONCONTIGUOUS-P -- are now different, which I find confusing. > `region-noncontiguous-p' doesn't relate to the `interactive' form at all, but > rather solely to this new behavior, internal to shell-command-on-region. ^ permalink raw reply [flat|nested] 765+ messages in thread
* RE: Feature freezes and Emacs 25 2015-11-11 0:17 ` Juri Linkov 2015-11-11 1:16 ` John Wiegley @ 2015-11-11 1:21 ` Drew Adams 1 sibling, 0 replies; 765+ messages in thread From: Drew Adams @ 2015-11-11 1:21 UTC (permalink / raw) To: Juri Linkov, emacs-devel > I'm designing a framework > to support multiple regions by adding a new arg with a group of regions. > > In bug#19829 I've collected the evidence of commands that need this > feature as a basis for the new design, but the deadlock was caused by the > same question that backpedaled the Alan's design: whether to add a new arg > to the existing functions or to try stuffing it into the existing ones? FWIW, with Isearch+ you can search or query-replace multiple regions (which can be defined in several ways, including just by their limits), including across multiple buffers. But I'm glad that you're adding this to isearch.el and also providing rectangle search, even if it means additional Isearch+ work. ;-) ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Feature freezes and Emacs 25 2015-11-07 1:53 ` Feature freezes and Emacs 25 (was: Dynamic loading progress) John Wiegley 2015-11-07 8:32 ` Feature freezes and Emacs 25 David Kastrup 2015-11-07 8:33 ` Feature freezes and Emacs 25 (was: Dynamic loading progress) Eli Zaretskii @ 2015-11-07 10:59 ` Phillip Lord 2015-11-07 14:20 ` kqueue in Emacs 25.1? (was: Feature freezes and Emacs 25) Michael Albinus 3 siblings, 0 replies; 765+ messages in thread From: Phillip Lord @ 2015-11-07 10:59 UTC (permalink / raw) To: emacs-devel John Wiegley <jwiegley@gmail.com> writes: > Since Emacs 25 is not yet released, the transfer of maintainership comes at a > slightly awkward time. I haven't fully caught my breath yet, but don't want to > impede Stefan's legacy from getting out the door. > > Let us officially freeze in one weeks, next Friday, Nov 13 at 11:59 PM UTC, so > that any ready, last minute features can get in before 25.1 is closed. Then > we'll take a pause and review whether anything should be allowed after the > freeze. Once we're comfortable with the bug situation, we release. > > I'd like to take a somewhat generous period for bug fixes, with feature work > happening in the meanwhile on topic branches. All severe bugs should either be > closed, or consciously deferred, before letting 25 out the door. If possible, I'd like to get my branch fix/no-undo-boundary-on-secondary-buffer-change in as well. It's not a huge change (in terms of size), although it's quite significant in that it affects nearly every keypress in Emacs because it changes the undo system. It changes a behaviour which is breaking my current package, and which cannot be worked around in lisp (at least not sanely). Phil ^ permalink raw reply [flat|nested] 765+ messages in thread
* kqueue in Emacs 25.1? (was: Feature freezes and Emacs 25) 2015-11-07 1:53 ` Feature freezes and Emacs 25 (was: Dynamic loading progress) John Wiegley ` (2 preceding siblings ...) 2015-11-07 10:59 ` Phillip Lord @ 2015-11-07 14:20 ` Michael Albinus 2015-11-07 14:39 ` Eli Zaretskii 2015-11-07 14:52 ` kqueue in Emacs 25.1? Wolfgang Jenkner 3 siblings, 2 replies; 765+ messages in thread From: Michael Albinus @ 2015-11-07 14:20 UTC (permalink / raw) To: emacs-devel John Wiegley <jwiegley@gmail.com> writes: > Let us officially freeze in one weeks, next Friday, Nov 13 at 11:59 PM UTC, so > that any ready, last minute features can get in before 25.1 is closed. Then > we'll take a pause and review whether anything should be allowed after the > freeze. Once we're comfortable with the bug situation, we release. The topic itself has been discussed a while ago: shall kqueue support be added to the file notification backends? kqueue is the native file notification library for all BSD-like systems, including Mac OS. The answer that time was NO, because - kqueue is already supported implicitely by gfilenotify, and - it is said to have a horrible API. Time passes, and at least the first argument is not valid any more. Due to Bug#20280 we know, that gfilenotify cannot be used on systems which have defined HAVE_NS. No file notification support on Mac OS, therefore. The second argument is still valid, but ... I have started a while ago to write kqueue.c, in order to have also kqueue support in Emacs. Just my little pet project, looking whether it's possible. Slow progress, 'tho. The question is: assumed I succeed with this (point 2 of the arguments is still valid), would kqueue support be accepted in Emacs? And in case of yes, shall I concentrate on this task next time, in order to finish before feature freeze? Note, that I haven't anything to present yet, I'm still fighting with the API. And I develop under Ubuntu, *real* tests must be performed by somebody else. > John Best regards, Michael. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? (was: Feature freezes and Emacs 25) 2015-11-07 14:20 ` kqueue in Emacs 25.1? (was: Feature freezes and Emacs 25) Michael Albinus @ 2015-11-07 14:39 ` Eli Zaretskii 2015-11-07 14:53 ` kqueue in Emacs 25.1? Michael Albinus 2015-11-07 14:52 ` kqueue in Emacs 25.1? Wolfgang Jenkner 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-07 14:39 UTC (permalink / raw) To: Michael Albinus; +Cc: emacs-devel > From: Michael Albinus <michael.albinus@gmx.de> > Date: Sat, 07 Nov 2015 15:20:23 +0100 > > I have started a while ago to write kqueue.c, in order to have also > kqueue support in Emacs. Just my little pet project, looking whether > it's possible. Slow progress, 'tho. > > The question is: assumed I succeed with this (point 2 of the arguments > is still valid), would kqueue support be accepted in Emacs? And in case > of yes, shall I concentrate on this task next time, in order to finish > before feature freeze? > > Note, that I haven't anything to present yet, I'm still fighting with > the API. And I develop under Ubuntu, *real* tests must be performed by > somebody else. Can you estimate how soon can you have a test-ready implementation? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-07 14:39 ` Eli Zaretskii @ 2015-11-07 14:53 ` Michael Albinus 2015-11-07 15:26 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Michael Albinus @ 2015-11-07 14:53 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> Note, that I haven't anything to present yet, I'm still fighting with >> the API. And I develop under Ubuntu, *real* tests must be performed by >> somebody else. > > Can you estimate how soon can you have a test-ready implementation? Don't know. Maybe end of this week I could push something into a scratch branch. It depends, whether there is a chance to be accepted; I would give it priority then. Best regards, Michael. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-07 14:53 ` kqueue in Emacs 25.1? Michael Albinus @ 2015-11-07 15:26 ` Eli Zaretskii 2015-11-09 22:31 ` John Wiegley 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-07 15:26 UTC (permalink / raw) To: Michael Albinus; +Cc: emacs-devel > From: Michael Albinus <michael.albinus@gmx.de> > Cc: emacs-devel@gnu.org > Date: Sat, 07 Nov 2015 15:53:40 +0100 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> Note, that I haven't anything to present yet, I'm still fighting with > >> the API. And I develop under Ubuntu, *real* tests must be performed by > >> somebody else. > > > > Can you estimate how soon can you have a test-ready implementation? > > Don't know. Maybe end of this week I could push something into a scratch > branch. It depends, whether there is a chance to be accepted; I would > give it priority then. IMO, if it's just one week away, we should wait for it. John? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-07 15:26 ` Eli Zaretskii @ 2015-11-09 22:31 ` John Wiegley 2015-11-10 13:56 ` Michael Albinus 0 siblings, 1 reply; 765+ messages in thread From: John Wiegley @ 2015-11-09 22:31 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Michael Albinus, emacs-devel >>>>> Eli Zaretskii <eliz@gnu.org> writes: > IMO, if it's just one week away, we should wait for it. John? Agreed, let's exempt this from our feature freeze if it's that close. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-09 22:31 ` John Wiegley @ 2015-11-10 13:56 ` Michael Albinus 2015-11-10 14:32 ` Wolfgang Jenkner 0 siblings, 1 reply; 765+ messages in thread From: Michael Albinus @ 2015-11-10 13:56 UTC (permalink / raw) To: emacs-devel John Wiegley <jwiegley@gmail.com> writes: > Agreed, let's exempt this from our feature freeze if it's that close. Unfortunately, I am blocked. There seems to be an error in Ubuntu's libkqueue0 package, which prevents me from further testing. I could reproduce the problem with a very small test program outside Emacs, so I have reported this as Ubuntu bug <https://bugs.launchpad.net/ubuntu/+source/libkqueue/+bug/1514837>. Unless somebody shows me that I made an error, or this bug is fixed in Ubuntu, I cannot continue to work on this. I have no *BSD or Mac OS machine which I could use. I will collect everything what I have done so far, und push it as "scratch/kqueue" branch to git. > John Best regards, Michael. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-10 13:56 ` Michael Albinus @ 2015-11-10 14:32 ` Wolfgang Jenkner 2015-11-10 14:52 ` Michael Albinus 0 siblings, 1 reply; 765+ messages in thread From: Wolfgang Jenkner @ 2015-11-10 14:32 UTC (permalink / raw) To: Michael Albinus; +Cc: emacs-devel On Tue, Nov 10 2015, Michael Albinus wrote: > I could > reproduce the problem with a very small test program outside Emacs, so I > have reported this as Ubuntu bug > <https://bugs.launchpad.net/ubuntu/+source/libkqueue/+bug/1514837>. I compiled your test program (after adding #include <sys/types.h> at the top, see kqueue(2)) on FreeBSD 10 and it seems to work as expected? [1 ~]$ cd /tmp/ [2 /tmp]$ cc -Wall julipedia.c -o julipedia [3 /tmp]$ touch foo [4 /tmp]$ ./julipedia >/dev/pts/7 2>&1 [5 /tmp]$ And on the other terminal: [1 ~]$ tty /dev/pts/7 [2 ~]$ cd /tmp/ [3 /tmp]$ echo >foo [4 /tmp]$ File written File extended File attributes modified [4 /tmp]$ echo >>foo [5 /tmp]$ File written File extended [5 /tmp]$ chmod a+x foo File attributes modified [6 /tmp]$ rm foo File deleted [7 /tmp]$ ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-10 14:32 ` Wolfgang Jenkner @ 2015-11-10 14:52 ` Michael Albinus 2015-11-11 11:41 ` Michael Albinus 0 siblings, 1 reply; 765+ messages in thread From: Michael Albinus @ 2015-11-10 14:52 UTC (permalink / raw) To: emacs-devel Wolfgang Jenkner <wjenkner@inode.at> writes: Hi Wolfgang, > I compiled your test program (after adding #include <sys/types.h> at the > top, see kqueue(2)) on FreeBSD 10 and it seems to work as expected? Yes. That's what I expect under BSD! > [1 ~]$ cd /tmp/ > [2 /tmp]$ cc -Wall julipedia.c -o julipedia > [3 /tmp]$ touch foo > [4 /tmp]$ ./julipedia >/dev/pts/7 2>&1 > [5 /tmp]$ > > And on the other terminal: > > [1 ~]$ tty > /dev/pts/7 > [2 ~]$ cd /tmp/ > [3 /tmp]$ echo >foo > [4 /tmp]$ File written > File extended > File attributes modified > > [4 /tmp]$ echo >>foo > [5 /tmp]$ File written > File extended > > [5 /tmp]$ chmod a+x foo > File attributes modified > [6 /tmp]$ rm foo > File deleted > [7 /tmp]$ Whatever I do with /tmp/foo, I see always File written File extended File attributes modified File link count changed File renamed File deleted No chance to find out which action was triggered :-( I'm just polishing my code a little bit, and then I will push it as branch scratch/kqueue. Then you have something to play with it :-) First of all, I would like to know whether it compiles and links under BSD the way I have changed it in configure.ac and src/Makefile.in. Thanks for your testing, and best regards, Michael. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-10 14:52 ` Michael Albinus @ 2015-11-11 11:41 ` Michael Albinus 2015-11-11 15:11 ` Wolfgang Jenkner 2015-11-11 15:37 ` Wolfgang Jenkner 0 siblings, 2 replies; 765+ messages in thread From: Michael Albinus @ 2015-11-11 11:41 UTC (permalink / raw) To: emacs-devel Michael Albinus <michael.albinus@gmx.de> writes: Hi Wolfgang, > I'm just polishing my code a little bit, and then I will push it as > branch scratch/kqueue. Then you have something to play with it :-) I've pushed this branch to savannah. > First of all, I would like to know whether it compiles and links under > BSD the way I have changed it in configure.ac and src/Makefile.in. Could you, pls, check in your environment? You could also play a little bit with `kqueue-add-watch', but be aware that watching directories is not implemented yet. This must be emulated, kqueue has no native support for watching directories. Best regards, Michael. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-11 11:41 ` Michael Albinus @ 2015-11-11 15:11 ` Wolfgang Jenkner 2015-11-11 15:44 ` Michael Albinus 2015-11-11 15:37 ` Wolfgang Jenkner 1 sibling, 1 reply; 765+ messages in thread From: Wolfgang Jenkner @ 2015-11-11 15:11 UTC (permalink / raw) To: Michael Albinus; +Cc: emacs-devel On Wed, Nov 11 2015, Michael Albinus wrote: > I've pushed this branch to savannah. Thank you very much! > >> First of all, I would like to know whether it compiles and links under >> BSD the way I have changed it in configure.ac and src/Makefile.in. > > Could you, pls, check in your environment? Please, see the patch with trivial fixes below. > You could also play a little bit with `kqueue-add-watch', but be aware > that watching directories is not implemented yet. This must be emulated, > kqueue has no native support for watching directories. Doing the same tests as with julipedia: echo >foo (7 (attrib) "/tmp/foo") (7 (extend write) "/tmp/foo") echo >>foo (7 (extend write) "/tmp/foo") chmod a+x foo (7 (attrib) "/tmp/foo") rm foo (7 (delete) "/tmp/foo") -- >8 -- Subject: [PATCH] Build fixes for kqueue support. * src/kqueue.c (Fkqueue_add_watch): O_BINARY is not a POSIX open(3) flag. * configure.ac (HAVE_KQUEUE): There is no pkg-config module for native kqueue on *BSD. --- configure.ac | 7 +++++++ src/kqueue.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 9c6db56..f9274d7 100644 --- a/configure.ac +++ b/configure.ac @@ -2732,6 +2732,13 @@ case $with_file_notification,$NOTIFY_OBJ in NOTIFY_LIBS=$KQUEUE_LIBS NOTIFY_OBJ=kqueue.o NOTIFY_SUMMARY="yes -lkqueue" + else + AC_SEARCH_LIBS(kqueue, []) + if test "$ac_cv_search_kqueue" != no; then + AC_DEFINE(HAVE_KQUEUE, 1, [Define to 1 to use kqueue.]) + NOTIFY_OBJ=kqueue.o + NOTIFY_SUMMARY="yes (kqueue)" + fi fi ;; esac diff --git a/src/kqueue.c b/src/kqueue.c index c2e859f..d2f3d37 100644 --- a/src/kqueue.c +++ b/src/kqueue.c @@ -163,7 +163,7 @@ will be reported only in case of the `rename' event. */) /* Open file. */ file = ENCODE_FILE (file); - fd = emacs_open (SSDATA (file), O_NONBLOCK | O_BINARY | O_RDONLY, 0); + fd = emacs_open (SSDATA (file), O_NONBLOCK | O_RDONLY, 0); if (fd == -1) report_file_error ("File cannot be opened", file); -- 2.6.2 ^ permalink raw reply related [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-11 15:11 ` Wolfgang Jenkner @ 2015-11-11 15:44 ` Michael Albinus 2015-11-11 16:02 ` Wolfgang Jenkner 0 siblings, 1 reply; 765+ messages in thread From: Michael Albinus @ 2015-11-11 15:44 UTC (permalink / raw) To: emacs-devel Wolfgang Jenkner <wjenkner@inode.at> writes: Hi Wolfgang, > Please, see the patch with trivial fixes below. Feel free to commit them to the branch. >> You could also play a little bit with `kqueue-add-watch', but be aware >> that watching directories is not implemented yet. This must be emulated, >> kqueue has no native support for watching directories. > > Doing the same tests as with julipedia: > > echo >foo > (7 (attrib) "/tmp/foo") (7 (extend write) "/tmp/foo") > > echo >>foo > (7 (extend write) "/tmp/foo") > > chmod a+x foo > (7 (attrib) "/tmp/foo") > > rm foo > (7 (delete) "/tmp/foo") All of this looks good to me. I will see whether I could downgrade libkqueue0 on my Ubuntu system to an earlier version, which works correctly. Then I could continue to work on this. Best regards, Michael. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-11 15:44 ` Michael Albinus @ 2015-11-11 16:02 ` Wolfgang Jenkner 2015-11-11 16:48 ` Michael Albinus 0 siblings, 1 reply; 765+ messages in thread From: Wolfgang Jenkner @ 2015-11-11 16:02 UTC (permalink / raw) To: Michael Albinus; +Cc: emacs-devel On Wed, Nov 11 2015, Michael Albinus wrote: >> Please, see the patch with trivial fixes below. > > Feel free to commit them to the branch. Done. Wolfgang ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-11 16:02 ` Wolfgang Jenkner @ 2015-11-11 16:48 ` Michael Albinus 0 siblings, 0 replies; 765+ messages in thread From: Michael Albinus @ 2015-11-11 16:48 UTC (permalink / raw) To: emacs-devel Wolfgang Jenkner <wjenkner@inode.at> writes: >> Feel free to commit them to the branch. > > Done. Thanks. > Wolfgang Best regards, Michael. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-11 11:41 ` Michael Albinus 2015-11-11 15:11 ` Wolfgang Jenkner @ 2015-11-11 15:37 ` Wolfgang Jenkner 2015-11-11 15:52 ` Michael Albinus 1 sibling, 1 reply; 765+ messages in thread From: Wolfgang Jenkner @ 2015-11-11 15:37 UTC (permalink / raw) To: Michael Albinus; +Cc: emacs-devel On Wed, Nov 11 2015, Michael Albinus wrote: > This must be emulated, > kqueue has no native support for watching directories. In the sense that a directory can be watched (it's a vnode type) but it is not so straightforward to find out what exactly has changed when, say, a `write' event arrives for it? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-11 15:37 ` Wolfgang Jenkner @ 2015-11-11 15:52 ` Michael Albinus 2015-11-12 17:59 ` Michael Albinus 0 siblings, 1 reply; 765+ messages in thread From: Michael Albinus @ 2015-11-11 15:52 UTC (permalink / raw) To: emacs-devel Wolfgang Jenkner <wjenkner@inode.at> writes: >> This must be emulated, >> kqueue has no native support for watching directories. > > In the sense that a directory can be watched (it's a vnode type) but it > is not so straightforward to find out what exactly has changed when, > say, a `write' event arrives for it? Yes. I've studied the code in libinotify-kqueue and in the glib/gio/kqueue backend. Both seem to scan the directory for changes, once there is a "something has changed" kqueue event for a directory. I plan to implement it based on directory_files_internal (in dired.c). This is the working horse of directory-files-and-attributes. Btw, in case you don't know it yet: <http://people.freebsd.org/~jlemon/papers/kqueue.pdf> gives a pretty good overview about kqueue. Best regards, Michael. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-11 15:52 ` Michael Albinus @ 2015-11-12 17:59 ` Michael Albinus 2015-11-12 18:34 ` Wolfgang Jenkner 0 siblings, 1 reply; 765+ messages in thread From: Michael Albinus @ 2015-11-12 17:59 UTC (permalink / raw) To: emacs-devel Michael Albinus <michael.albinus@gmx.de> writes: Hi Wolfgang, >> In the sense that a directory can be watched (it's a vnode type) but it >> is not so straightforward to find out what exactly has changed when, >> say, a `write' event arrives for it? > > Yes. I've studied the code in libinotify-kqueue and in the > glib/gio/kqueue backend. Both seem to scan the directory for changes, > once there is a "something has changed" kqueue event for a directory. > > I plan to implement it based on directory_files_internal (in > dired.c). This is the working horse of directory-files-and-attributes. Could you pls run a test for me? In julipedia.c, pls change "/tmp/foo" to "/tmp". Start it, and do some file operations in /tmp. What happens? Here under Ubuntu, it crashes immediately. Seems to be another bug :-( I've tried to downgrade libkqueue0 from 2.0.3 to 1.0.4, but same problems ... TIA, and best regards, Michael. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-12 17:59 ` Michael Albinus @ 2015-11-12 18:34 ` Wolfgang Jenkner 2015-11-13 10:09 ` Michael Albinus 0 siblings, 1 reply; 765+ messages in thread From: Wolfgang Jenkner @ 2015-11-12 18:34 UTC (permalink / raw) To: Michael Albinus; +Cc: emacs-devel On Thu, Nov 12 2015, Michael Albinus wrote: > Could you pls run a test for me? In julipedia.c, pls change "/tmp/foo" > to "/tmp". Start it, and do some file operations in /tmp. What happens? [1 ~]$ cd /tmp/ [2 /tmp]$ ./julipedia & [1] 13728 [3 /tmp]$ touch x File written [4 /tmp]$ mv x y File written [5 /tmp]$ rm y [6 /tmp]$ File written [6 /tmp]$ I've seen only `write' events here. Wolfgang ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-12 18:34 ` Wolfgang Jenkner @ 2015-11-13 10:09 ` Michael Albinus 2015-11-13 13:00 ` Wolfgang Jenkner 0 siblings, 1 reply; 765+ messages in thread From: Michael Albinus @ 2015-11-13 10:09 UTC (permalink / raw) To: emacs-devel Wolfgang Jenkner <wjenkner@inode.at> writes: >> Could you pls run a test for me? In julipedia.c, pls change "/tmp/foo" >> to "/tmp". Start it, and do some file operations in /tmp. What happens? > > [1 ~]$ cd /tmp/ > [2 /tmp]$ ./julipedia & > [1] 13728 > [3 /tmp]$ touch x > File written > [4 /tmp]$ mv x y > File written > [5 /tmp]$ rm y > [6 /tmp]$ File written > > [6 /tmp]$ > > I've seen only `write' events here. Well, that's as expected. Do you know a *BSD VM I could download? It shall be prepared to compile and run Emacs; I don't know too much how to install a proper environment for Emacs under *BSD. > Wolfgang Best regards, Michael. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-13 10:09 ` Michael Albinus @ 2015-11-13 13:00 ` Wolfgang Jenkner 2015-11-13 14:57 ` Wolfgang Jenkner 2015-11-13 16:23 ` Michael Albinus 0 siblings, 2 replies; 765+ messages in thread From: Wolfgang Jenkner @ 2015-11-13 13:00 UTC (permalink / raw) To: Michael Albinus; +Cc: emacs-devel On Fri, Nov 13 2015, Michael Albinus wrote: > Do you know a *BSD VM I could download? It shall be prepared to compile > and run Emacs; I don't know too much how to install a proper environment > for Emacs under *BSD. The official FreeBSD VM images contain a complete base system, including a working (clang) toolchain, see https://www.freebsd.org/where.html I'd suggest one of ftp://ftp.freebsd.org/pub/FreeBSD/releases/VM-IMAGES/10.2-RELEASE/amd64/Latest/ see ftp://ftp.freebsd.org/pub/FreeBSD/releases/VM-IMAGES/README.txt (I've just tried the .raw disk image under qemu and compiled a simple hello world program, which works fine. Also, storage is persistent in this case, i.e., the test program was still there after rebooting the VM.) Almost everything should be there to compile a non-X emacs from source, with the exception of GNU make (gmake) and pkg-config (actually pkgconf, a compatible replacement without glib dependency). If you can bring up the network in the emulator (with DHCP everything should be automatic), `pkg install gmake pkgconf' should do the trick. Mounting ext2fs loopback (in GNU/Linux parlance) disk images should also work r/w. For any questions, please feel free to email me (I think they would be slightly off topic for the list...). Wolfgang ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-13 13:00 ` Wolfgang Jenkner @ 2015-11-13 14:57 ` Wolfgang Jenkner 2015-11-13 16:23 ` Michael Albinus 1 sibling, 0 replies; 765+ messages in thread From: Wolfgang Jenkner @ 2015-11-13 14:57 UTC (permalink / raw) To: Michael Albinus; +Cc: emacs-devel On Fri, Nov 13 2015, Wolfgang Jenkner wrote: > If you can bring up the network in the emulator (with DHCP everything > should be automatic), Ahem, sorry, not quite automatic $ cat /etc/rc.conf hostname="xx.yy.zz" ifconfig_em0="DHCP" where em0 must be replaced by the name of the network device as shown by ifconfig (or dmesg), see https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/network-dhcp.html Wolfgang ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-13 13:00 ` Wolfgang Jenkner 2015-11-13 14:57 ` Wolfgang Jenkner @ 2015-11-13 16:23 ` Michael Albinus 2015-11-16 11:58 ` Michael Albinus 1 sibling, 1 reply; 765+ messages in thread From: Michael Albinus @ 2015-11-13 16:23 UTC (permalink / raw) To: emacs-devel Wolfgang Jenkner <wjenkner@inode.at> writes: > I'd suggest one of > > ftp://ftp.freebsd.org/pub/FreeBSD/releases/VM-IMAGES/10.2-RELEASE/amd64/Latest/ Thanks for this, I'll try it. > For any questions, please feel free to email me (I think they would be > slightly off topic for the list...). For sure :-) > Wolfgang Best regards, Michael. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-13 16:23 ` Michael Albinus @ 2015-11-16 11:58 ` Michael Albinus 2015-11-17 3:50 ` John Wiegley 0 siblings, 1 reply; 765+ messages in thread From: Michael Albinus @ 2015-11-16 11:58 UTC (permalink / raw) To: emacs-devel Michael Albinus <michael.albinus@gmx.de> writes: > Wolfgang Jenkner <wjenkner@inode.at> writes: > >> I'd suggest one of >> >> ftp://ftp.freebsd.org/pub/FreeBSD/releases/VM-IMAGES/10.2-RELEASE/amd64/Latest/ > > Thanks for this, I'll try it. Thanks to the support by Wolfgang, I could continue implementing kqueue integration for Emacs. The code in branch scratch/kqueue is working pretty well on FreeBSD 10.2. The example in the Elisp manual runs proper except the notification of file attribute changes. This is a minor problem only; other file notification backends have also problems with this. test/automated/auto-revert-tests.el passes. test/automated/file-notify-tests.el shows two failed test cases. According to my debugging, it is not a problem of the kqueue backend itself, but a problem how this test suite tries to catch file notification events. Also a minor problem I would say. How to continue? There are several options: * Merge the branch into the emacs-25 branch. * Merge the branch into the master branch. * Keep the code still in this branch for a while. Personally, I'm in favor of the first option. In any case: People using *BSD or Mac OS are encouraged to run their own tests. Best regards, Michael. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-16 11:58 ` Michael Albinus @ 2015-11-17 3:50 ` John Wiegley 2015-11-17 9:37 ` Michael Albinus 2015-11-25 14:35 ` kqueue in Emacs 25? Michael Albinus 0 siblings, 2 replies; 765+ messages in thread From: John Wiegley @ 2015-11-17 3:50 UTC (permalink / raw) To: Michael Albinus; +Cc: emacs-devel >>>>> Michael Albinus <michael.albinus@gmx.de> writes: > Thanks to the support by Wolfgang, I could continue implementing kqueue > integration for Emacs. The code in branch scratch/kqueue is working pretty > well on FreeBSD 10.2. The example in the Elisp manual runs proper except the > notification of file attribute changes. This is a minor problem only; other > file notification backends have also problems with this. Hi Michael, I think this work should continue on its branch until you at least have the tests working, and then merge it into master. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-17 3:50 ` John Wiegley @ 2015-11-17 9:37 ` Michael Albinus 2015-11-25 14:35 ` kqueue in Emacs 25? Michael Albinus 1 sibling, 0 replies; 765+ messages in thread From: Michael Albinus @ 2015-11-17 9:37 UTC (permalink / raw) To: emacs-devel John Wiegley <jwiegley@gmail.com> writes: > Hi Michael, Hi John, > I think this work should continue on its branch until you at least have the > tests working, and then merge it into master. Will do. > John Best regards, Michael. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25? 2015-11-17 3:50 ` John Wiegley 2015-11-17 9:37 ` Michael Albinus @ 2015-11-25 14:35 ` Michael Albinus 2015-11-25 18:53 ` John Wiegley 1 sibling, 1 reply; 765+ messages in thread From: Michael Albinus @ 2015-11-25 14:35 UTC (permalink / raw) To: emacs-devel John Wiegley <jwiegley@gmail.com> writes: > Hi Michael, Hi everybody, > I think this work should continue on its branch until you at least have the > tests working, and then merge it into master. I have merged branch scratch/kqueue into master. This adds the kqueue file notification library for Emacsen running under *BSD or Mac OS. Running "./configure; make" shall enable it on such machines. The configure output reports, whether it has been enabled. If this doesn't happen automatically, pls report. Alternatively, you can enable it by calling ./configure --with-file-notification=kqueue The file notification test suite runs via make -C test/automated file-notify-tests Be patient, some of the tests take their time. Pls report also, if it doesn't work for you. > John Best regards, Michael. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25? 2015-11-25 14:35 ` kqueue in Emacs 25? Michael Albinus @ 2015-11-25 18:53 ` John Wiegley 0 siblings, 0 replies; 765+ messages in thread From: John Wiegley @ 2015-11-25 18:53 UTC (permalink / raw) To: Michael Albinus; +Cc: emacs-devel >>>>> Michael Albinus <michael.albinus@gmx.de> writes: > I have merged branch scratch/kqueue into master. This adds the kqueue file > notification library for Emacsen running under *BSD or Mac OS. This is great news, Michael, thank you! I'd been wanting file notifications on OS X for a while. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-07 14:20 ` kqueue in Emacs 25.1? (was: Feature freezes and Emacs 25) Michael Albinus 2015-11-07 14:39 ` Eli Zaretskii @ 2015-11-07 14:52 ` Wolfgang Jenkner 2015-11-07 15:02 ` Wolfgang Jenkner 2015-11-07 18:57 ` Michael Albinus 1 sibling, 2 replies; 765+ messages in thread From: Wolfgang Jenkner @ 2015-11-07 14:52 UTC (permalink / raw) To: Michael Albinus; +Cc: emacs-devel On Sat, Nov 07 2015, Michael Albinus wrote: > The topic itself has been discussed a while ago: shall kqueue support be > added to the file notification backends? I'd say it depends on how you implement it: if you are trying to emulate the inotify API it might be better to just link with libinotify-kqueue https://github.com/dmatveev/libinotify-kqueue On the other hand, if you are writing "native" support for kqueue, that would be awesome :-) As for emacs with libinotify-kqueue, I've tried this on FreeBSD 10-STABLE (before your recent changes to the notify stuff, though) and it seems to work well when watching small directories, but emacs somehow locks up for directories with more than 1500 files or so (while using, say, inotifywait from inotify-tools seems to work without problems for larger directories). Here's the trivial patch for libinotify support, by the way: -- >8 -- Subject: [PATCH] Tentative libinotify support. --- configure.ac | 13 +++++++++---- src/Makefile.in | 4 +++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 83d45a9..4216821 100644 --- a/configure.ac +++ b/configure.ac @@ -2696,19 +2696,24 @@ case $with_file_notification,$opsys in fi ;; esac -dnl inotify is available only on GNU/Linux. +dnl inotify is available on GNU/Linux, and on *BSD via libinotify. case $with_file_notification,$NOTIFY_OBJ in inotify, | yes,) AC_CHECK_HEADER(sys/inotify.h) if test "$ac_cv_header_sys_inotify_h" = yes ; then - AC_CHECK_FUNC(inotify_init1) - if test "$ac_cv_func_inotify_init1" = yes; then + AC_SEARCH_LIBS(inotify_init1, inotify) + if test "$ac_cv_search_inotify_init1" != no; then AC_DEFINE(HAVE_INOTIFY, 1, [Define to 1 to use inotify.]) NOTIFY_OBJ=inotify.o - NOTIFY_SUMMARY="yes -lglibc (inotify)" + LIB_INOTIFY= + if test "$ac_cv_search_inotify_init1" != "none required"; then + LIB_INOTIFY="$ac_cv_search_inotify_init1" + fi + NOTIFY_SUMMARY="yes $LIB_INOTIFY (inotify)" fi fi ;; esac +AC_SUBST(LIB_INOTIFY) dnl g_file_monitor exists since glib 2.18. G_FILE_MONITOR_EVENT_MOVED dnl has been added in glib 2.24. It has been tested under diff --git a/src/Makefile.in b/src/Makefile.in index 9c0a3bb..bb9c003 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -153,6 +153,8 @@ DBUS_OBJ = @DBUS_OBJ@ LIB_EXECINFO=@LIB_EXECINFO@ +LIB_INOTIFY=@LIB_INOTIFY@ + SETTINGS_CFLAGS = @SETTINGS_CFLAGS@ SETTINGS_LIBS = @SETTINGS_LIBS@ @@ -468,7 +470,7 @@ LIBES = $(LIBS) $(W32_LIBS) $(LIBS_GNUSTEP) $(LIBX_BASE) $(LIBIMAGE) \ $(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \ $(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \ $(LIBGNUTLS_LIBS) $(LIB_PTHREAD) \ - $(GFILENOTIFY_LIBS) $(LIB_MATH) $(LIBZ) + $(GFILENOTIFY_LIBS) $(LIB_INOTIFY) $(LIB_MATH) $(LIBZ) $(leimdir)/leim-list.el: bootstrap-emacs$(EXEEXT) $(MAKE) -C ../leim leim-list.el EMACS="$(bootstrap_exe)" -- 2.6.2 ^ permalink raw reply related [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-07 14:52 ` kqueue in Emacs 25.1? Wolfgang Jenkner @ 2015-11-07 15:02 ` Wolfgang Jenkner 2015-11-08 6:33 ` Paul Eggert 2015-11-07 18:57 ` Michael Albinus 1 sibling, 1 reply; 765+ messages in thread From: Wolfgang Jenkner @ 2015-11-07 15:02 UTC (permalink / raw) To: Michael Albinus; +Cc: emacs-devel On Sat, Nov 07 2015, Wolfgang Jenkner wrote: > I'd say it depends on how you implement it: if you are trying to emulate > the inotify API it might be better to just link with libinotify-kqueue I should add that one difference between libinotify-kqueue and native GNU/Linux inotify is that libinotify uses a separate worker-thread. This is a difference that can become visible sometimes (at least in the current implementation), e.g., the worker thread doesn't block most signals, so the effect of signal handlers can be delayed until control returns to the main thread. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-07 15:02 ` Wolfgang Jenkner @ 2015-11-08 6:33 ` Paul Eggert 2015-11-08 12:38 ` Wolfgang Jenkner 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-08 6:33 UTC (permalink / raw) To: Wolfgang Jenkner; +Cc: emacs-devel Wolfgang Jenkner wrote: > one difference between libinotify-kqueue and native > GNU/Linux inotify is that libinotify uses a separate worker-thread. > This is a difference that can become visible sometimes (at least in the > current implementation), e.g., the worker thread doesn't block most > signals, so the effect of signal handlers can be delayed until control > returns to the main thread. Can you elaborate on why this is an issue? If the worker thread doesn't block (say) SIGCHLD, the thread should call deliver_child_signal, which calls deliver_process_signal, which (a) calls pthread_sigmask to arrange for the worker thread to block SIGCHLD indefinitely so that the failure-to-block problem doesn't recur, and (b) calls pthread_kill (main_thread, SIGCHLD) to forward the signal to the main thread just this once. When you write "can be delayed" are you referring to the delay in (b), or to some other delay? And what are the symptoms of the delay? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-08 6:33 ` Paul Eggert @ 2015-11-08 12:38 ` Wolfgang Jenkner 0 siblings, 0 replies; 765+ messages in thread From: Wolfgang Jenkner @ 2015-11-08 12:38 UTC (permalink / raw) To: Paul Eggert; +Cc: emacs-devel On Sat, Nov 07 2015, Paul Eggert wrote: > Can you elaborate on why this is an issue? I wasn't talking of emacs here. I just meant that applications in general don't expect an extra thread after calling inotify_init(), because there is none on GNU/Linux (I think). The special situation that I had in mind was a glitch in inotifywatch due to this, see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=204366 ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-07 14:52 ` kqueue in Emacs 25.1? Wolfgang Jenkner 2015-11-07 15:02 ` Wolfgang Jenkner @ 2015-11-07 18:57 ` Michael Albinus 2015-11-07 22:22 ` Wolfgang Jenkner 1 sibling, 1 reply; 765+ messages in thread From: Michael Albinus @ 2015-11-07 18:57 UTC (permalink / raw) To: emacs-devel Wolfgang Jenkner <wjenkner@inode.at> writes: > On Sat, Nov 07 2015, Michael Albinus wrote: > >> The topic itself has been discussed a while ago: shall kqueue support be >> added to the file notification backends? > > I'd say it depends on how you implement it: if you are trying to emulate > the inotify API it might be better to just link with libinotify-kqueue > > https://github.com/dmatveev/libinotify-kqueue Thanks for the link, it will be helpful to study that code. > On the other hand, if you are writing "native" support for kqueue, that > would be awesome :-) That's the plan. Would you be willing to help me with this, while coding, and (more important) testing on *BSD? Best regards, Michael. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: kqueue in Emacs 25.1? 2015-11-07 18:57 ` Michael Albinus @ 2015-11-07 22:22 ` Wolfgang Jenkner 0 siblings, 0 replies; 765+ messages in thread From: Wolfgang Jenkner @ 2015-11-07 22:22 UTC (permalink / raw) To: Michael Albinus; +Cc: emacs-devel On Sat, Nov 07 2015, Michael Albinus wrote: > Would you be willing to help me with this, while coding, and (more > important) testing on *BSD? I'll gladly test this on my FreeBSD 10 system, but I'm afraid I've yet to learn most about kqueue(2) by reading your code... ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-06 15:52 ` Ted Zlatanov 2015-11-06 15:55 ` Eli Zaretskii @ 2015-11-06 21:52 ` John Wiegley 2015-11-07 8:35 ` Eli Zaretskii 2015-11-08 11:02 ` Philipp Stephani 1 sibling, 2 replies; 765+ messages in thread From: John Wiegley @ 2015-11-06 21:52 UTC (permalink / raw) To: emacs-devel >>>>> Ted Zlatanov <tzz@lifelogs.com> writes: > I've tried to review the discussion so far and believe the code is > "functional enough." I think we got agreement from Stefan (probably John > too) to exempt dynamic modules from the feature freeze. If Eli and Stefan agree, you have my go ahead to integrate the code. If anyone else disagrees, please say so now. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-06 21:52 ` Dynamic loading progress John Wiegley @ 2015-11-07 8:35 ` Eli Zaretskii 2015-11-07 13:33 ` Ted Zlatanov 2015-11-08 11:02 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-07 8:35 UTC (permalink / raw) To: John Wiegley; +Cc: emacs-devel > From: John Wiegley <jwiegley@gmail.com> > Date: Fri, 06 Nov 2015 16:52:53 -0500 > > >>>>> Ted Zlatanov <tzz@lifelogs.com> writes: > > > I've tried to review the discussion so far and believe the code is > > "functional enough." I think we got agreement from Stefan (probably John > > too) to exempt dynamic modules from the feature freeze. > > If Eli and Stefan agree, you have my go ahead to integrate the code. If anyone > else disagrees, please say so now. I don't see any reasons to disagree. But adding such a feature, IME, needs more than just one week before we shake it up enough. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-07 8:35 ` Eli Zaretskii @ 2015-11-07 13:33 ` Ted Zlatanov 2015-11-07 13:48 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Ted Zlatanov @ 2015-11-07 13:33 UTC (permalink / raw) To: emacs-devel On Sat, 07 Nov 2015 10:35:39 +0200 Eli Zaretskii <eliz@gnu.org> wrote: >> From: John Wiegley <jwiegley@gmail.com> >> Date: Fri, 06 Nov 2015 16:52:53 -0500 >> >> >>>>> Ted Zlatanov <tzz@lifelogs.com> writes: >> >> > I've tried to review the discussion so far and believe the code is >> > "functional enough." I think we got agreement from Stefan (probably John >> > too) to exempt dynamic modules from the feature freeze. >> >> If Eli and Stefan agree, you have my go ahead to integrate the code. If anyone >> else disagrees, please say so now. EZ> I don't see any reasons to disagree. But adding such a feature, IME, EZ> needs more than just one week before we shake it up enough. I agree, but please recall it's been brewing for a very long time, so it's not something we just started. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-07 13:33 ` Ted Zlatanov @ 2015-11-07 13:48 ` Eli Zaretskii 2015-11-07 14:01 ` Ted Zlatanov 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-07 13:48 UTC (permalink / raw) To: emacs-devel > From: Ted Zlatanov <tzz@lifelogs.com> > Date: Sat, 07 Nov 2015 08:33:12 -0500 > > EZ> I don't see any reasons to disagree. But adding such a feature, IME, > EZ> needs more than just one week before we shake it up enough. > > I agree, but please recall it's been brewing for a very long time, so > it's not something we just started. I know. But if you mean to imply that a week might be enough, then I don't think so. As long as the feature is on a separate branch, it doesn't get enough exposure to users, neither wrt possible build-time complications, nor wrt run-time problems. There are just too many corner cases which are only visible once the feature is on master. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-07 13:48 ` Eli Zaretskii @ 2015-11-07 14:01 ` Ted Zlatanov 2015-11-07 17:47 ` Aurélien Aptel 2015-11-09 22:10 ` Dynamic loading progress John Wiegley 0 siblings, 2 replies; 765+ messages in thread From: Ted Zlatanov @ 2015-11-07 14:01 UTC (permalink / raw) To: emacs-devel On Sat, 07 Nov 2015 15:48:08 +0200 Eli Zaretskii <eliz@gnu.org> wrote: >> From: Ted Zlatanov <tzz@lifelogs.com> >> Date: Sat, 07 Nov 2015 08:33:12 -0500 >> EZ> I don't see any reasons to disagree. But adding such a feature, IME, EZ> needs more than just one week before we shake it up enough. >> >> I agree, but please recall it's been brewing for a very long time, so >> it's not something we just started. EZ> I know. But if you mean to imply that a week might be enough, then I EZ> don't think so. As long as the feature is on a separate branch, it EZ> doesn't get enough exposure to users, neither wrt possible build-time EZ> complications, nor wrt run-time problems. There are just too many EZ> corner cases which are only visible once the feature is on master. Yes, and that's exactly why we need it in master. I think 1 week is the time to feature freeze, but we have lots of time to fix bugs and issues. Changing the module ABI/API for instance is IMHO perfectly OK during the feature freeze. The feature is "dynamic modules" not a specific version thereof, until Emacs is released. Then it becomes "dynamic modules as defined by 25.1" and we have to live with them :) Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-07 14:01 ` Ted Zlatanov @ 2015-11-07 17:47 ` Aurélien Aptel 2015-11-08 11:16 ` Philipp Stephani 2015-11-09 22:10 ` Dynamic loading progress John Wiegley 1 sibling, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-11-07 17:47 UTC (permalink / raw) To: Emacs development discussions Well the repo is on github, dynamic-modules-2 branch. The changelog might need some work and we might want to move around some files but it's ready to merged in master, I think. https://github.com/aaptel/emacs-dynamic-module/tree/dynamic-modules-2 ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-07 17:47 ` Aurélien Aptel @ 2015-11-08 11:16 ` Philipp Stephani 2015-11-08 12:54 ` Steinar Bang 2015-11-08 13:08 ` Ted Zlatanov 0 siblings, 2 replies; 765+ messages in thread From: Philipp Stephani @ 2015-11-08 11:16 UTC (permalink / raw) To: Aurélien Aptel, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 645 bytes --] Aurélien Aptel <aurelien.aptel+emacs@gmail.com> schrieb am Sa., 7. Nov. 2015 um 18:47 Uhr: > Well the repo is on github, dynamic-modules-2 branch. The changelog > might need some work and we might want to move around some files but > it's ready to merged in master, I think. > > https://github.com/aaptel/emacs-dynamic-module/tree/dynamic-modules-2 > > In order to produce a clean patch, I tried merging the master (from emacs-mirror) or emacs-24 branch, but both produced too many merge conflicts (even in files untouched by the module code). Which upstream branch did you use to create the dynamic-modules-2 branch originally? [-- Attachment #2: Type: text/html, Size: 1054 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-08 11:16 ` Philipp Stephani @ 2015-11-08 12:54 ` Steinar Bang 2015-11-08 13:39 ` Philipp Stephani 2015-11-08 13:08 ` Ted Zlatanov 1 sibling, 1 reply; 765+ messages in thread From: Steinar Bang @ 2015-11-08 12:54 UTC (permalink / raw) To: emacs-devel >>>>> Philipp Stephani <p.stephani2@gmail.com>: > In order to produce a clean patch, I tried merging the master (from > emacs-mirror) or emacs-24 branch, but both produced too many merge > conflicts (even in files untouched by the module code). What kind of conflicts in what files? Could you provide some detail? What was the command line sequence you used to do the merges from master and emacs-24? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-08 12:54 ` Steinar Bang @ 2015-11-08 13:39 ` Philipp Stephani 0 siblings, 0 replies; 765+ messages in thread From: Philipp Stephani @ 2015-11-08 13:39 UTC (permalink / raw) To: emacs-devel [-- Attachment #1: Type: text/plain, Size: 937 bytes --] Steinar Bang <sb@dod.no> schrieb am So., 8. Nov. 2015 um 13:55 Uhr: > >>>>> Philipp Stephani <p.stephani2@gmail.com>: > > In order to produce a clean patch, I tried merging the master (from > > emacs-mirror) or emacs-24 branch, but both produced too many merge > > conflicts (even in files untouched by the module code). > > What kind of conflicts in what files? Could you provide some detail? > > Basically everywhere (more details probably wouldn't help). > What was the command line sequence you used to do the merges from master > and emacs-24? > > > I've added the GitHub emacs-mirror as origin, merged the to the master of Aurélien's fork, and then tried to merge that into the dynamics-module-2 branch. All with plain 'git merge'. However, I now managed to produce a two-step merge that didn't produce additional conflicts. I've now also merged in the Savannah master and pushed the result to my fork. [-- Attachment #2: Type: text/html, Size: 1493 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-08 11:16 ` Philipp Stephani 2015-11-08 12:54 ` Steinar Bang @ 2015-11-08 13:08 ` Ted Zlatanov 2015-11-08 13:42 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Ted Zlatanov @ 2015-11-08 13:08 UTC (permalink / raw) To: emacs-devel On Sun, 08 Nov 2015 11:16:53 +0000 Philipp Stephani <p.stephani2@gmail.com> wrote: PS> Aurélien Aptel <aurelien.aptel+emacs@gmail.com> schrieb am Sa., 7. Nov. PS> 2015 um 18:47 Uhr: >> Well the repo is on github, dynamic-modules-2 branch. The changelog >> might need some work and we might want to move around some files but >> it's ready to merged in master, I think. >> >> https://github.com/aaptel/emacs-dynamic-module/tree/dynamic-modules-2 >> >> PS> In order to produce a clean patch, I tried merging the master (from PS> emacs-mirror) or emacs-24 branch, but both produced too many merge PS> conflicts (even in files untouched by the module code). Which upstream PS> branch did you use to create the dynamic-modules-2 branch originally? Agreed. Aurélien, the diff is huge and there are many conflicts. It looks like the fork from master happened in February 2015 and you're simply out of date. Can you please rebase against the emacs.git origin/master? Last push... Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-08 13:08 ` Ted Zlatanov @ 2015-11-08 13:42 ` Philipp Stephani 2015-11-08 20:38 ` Ted Zlatanov 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-08 13:42 UTC (permalink / raw) To: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1380 bytes --] Ted Zlatanov <tzz@lifelogs.com> schrieb am So., 8. Nov. 2015 um 14:08 Uhr: > On Sun, 08 Nov 2015 11:16:53 +0000 Philipp Stephani <p.stephani2@gmail.com> > wrote: > > PS> Aurélien Aptel <aurelien.aptel+emacs@gmail.com> schrieb am Sa., 7. > Nov. > PS> 2015 um 18:47 Uhr: > > >> Well the repo is on github, dynamic-modules-2 branch. The changelog > >> might need some work and we might want to move around some files but > >> it's ready to merged in master, I think. > >> > >> https://github.com/aaptel/emacs-dynamic-module/tree/dynamic-modules-2 > >> > >> > PS> In order to produce a clean patch, I tried merging the master (from > PS> emacs-mirror) or emacs-24 branch, but both produced too many merge > PS> conflicts (even in files untouched by the module code). Which upstream > PS> branch did you use to create the dynamic-modules-2 branch originally? > > Agreed. Aurélien, the diff is huge and there are many conflicts. It > looks like the fork from master happened in February 2015 and you're > simply out of date. Can you please rebase against the emacs.git > origin/master? Last push... > Please check https://github.com/phst/emacs-dynamic-module/tree/dynamic-modules-2, it should have the current master merged in. Unfortunately I can't test that right now because for some reason make is incredibly slow on my machine after the merge. [-- Attachment #2: Type: text/html, Size: 2102 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-08 13:42 ` Philipp Stephani @ 2015-11-08 20:38 ` Ted Zlatanov 2015-11-09 10:40 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Ted Zlatanov @ 2015-11-08 20:38 UTC (permalink / raw) To: emacs-devel On Sun, 08 Nov 2015 13:42:21 +0000 Philipp Stephani <p.stephani2@gmail.com> wrote: PS> Ted Zlatanov <tzz@lifelogs.com> schrieb am So., 8. Nov. 2015 um 14:08 Uhr: >> Agreed. Aurélien, the diff is huge and there are many conflicts. It >> looks like the fork from master happened in February 2015 and you're >> simply out of date. Can you please rebase against the emacs.git >> origin/master? Last push... PS> Please check PS> https://github.com/phst/emacs-dynamic-module/tree/dynamic-modules-2, it PS> should have the current master merged in. PS> Unfortunately I can't test that right now because for some reason make is PS> incredibly slow on my machine after the merge. Sorry, Philipp, I don't know how you and Aurélien have collaborated in the past, and I've considered Aurélien's code authoritative. I don't want to bypass his review and approval, so maybe you can work with him on that? It will save us time instead of reviewing several times. Thank you! Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-08 20:38 ` Ted Zlatanov @ 2015-11-09 10:40 ` Aurélien Aptel 2015-11-09 10:48 ` Aurélien Aptel ` (4 more replies) 0 siblings, 5 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-11-09 10:40 UTC (permalink / raw) To: Emacs development discussions On Sun, Nov 8, 2015 at 9:38 PM, Ted Zlatanov <tzz@lifelogs.com> wrote: >>> Agreed. Aurélien, the diff is huge and there are many conflicts. It >>> looks like the fork from master happened in February 2015 and you're >>> simply out of date. Can you please rebase against the emacs.git >>> origin/master? Last push... I already merged master in my branch at some point, and did so with `merge --squash` IIRC, note to self: never do that again. Turns out it made any subsequent master merge a lot harder, sorry for that. The weird thing is most conflicting changes where actually identical but git couldn't tell. The diff were the same on both side but git couldnt tell they were from the same commits since they were squashed. > PS> Please check > PS> https://github.com/phst/emacs-dynamic-module/tree/dynamic-modules-2, it > PS> should have the current master merged in. > PS> Unfortunately I can't test that right now because for some reason make is > PS> incredibly slow on my machine after the merge. > > Sorry, Philipp, I don't know how you and Aurélien have collaborated in > the past, and I've considered Aurélien's code authoritative. I don't > want to bypass his review and approval, so maybe you can work with him > on that? It will save us time instead of reviewing several times. We've been working together on github, I've just merged his code. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-09 10:40 ` Aurélien Aptel @ 2015-11-09 10:48 ` Aurélien Aptel 2015-11-09 10:57 ` Yuri Khan ` (3 subsequent siblings) 4 siblings, 0 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-11-09 10:48 UTC (permalink / raw) To: Emacs development discussions Oh and also, I have an account on savannah (aaptel). Can I be added to the Emacs group and all other stuff commiters have access to? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-09 10:40 ` Aurélien Aptel 2015-11-09 10:48 ` Aurélien Aptel @ 2015-11-09 10:57 ` Yuri Khan 2015-11-09 11:46 ` Ted Zlatanov ` (2 subsequent siblings) 4 siblings, 0 replies; 765+ messages in thread From: Yuri Khan @ 2015-11-09 10:57 UTC (permalink / raw) To: Aurélien Aptel; +Cc: Emacs development discussions On Mon, Nov 9, 2015 at 4:40 PM, Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: > I already merged master in my branch at some point, and did so with > `merge --squash` IIRC, note to self: never do that again. Merge --squash is history rewriting, with all of the consequences thereof. > Turns out it > made any subsequent master merge a lot harder, sorry for that. The > weird thing is most conflicting changes where actually identical but > git couldn't tell. The diff were the same on both side but git couldnt > tell they were from the same commits since they were squashed. Typical symptoms of merging a branch with a rebased version of itself. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-09 10:40 ` Aurélien Aptel 2015-11-09 10:48 ` Aurélien Aptel 2015-11-09 10:57 ` Yuri Khan @ 2015-11-09 11:46 ` Ted Zlatanov 2015-11-09 12:27 ` Aurélien Aptel 2015-11-09 13:16 ` Steinar Bang 2015-11-10 9:35 ` Suggestion to enable git rerere by default Nicolas Richard 4 siblings, 1 reply; 765+ messages in thread From: Ted Zlatanov @ 2015-11-09 11:46 UTC (permalink / raw) To: emacs-devel On Mon, 9 Nov 2015 11:40:06 +0100 Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: AA> On Sun, Nov 8, 2015 at 9:38 PM, Ted Zlatanov <tzz@lifelogs.com> wrote: >> Sorry, Philipp, I don't know how you and Aurélien have collaborated in >> the past, and I've considered Aurélien's code authoritative. I don't >> want to bypass his review and approval, so maybe you can work with him >> on that? It will save us time instead of reviewing several times. AA> We've been working together on github, I've just merged his code. I checked this branch: `git fetch git@github.com:aaptel/emacs-dynamic-module.git dynamic-modules-2`? It's not been rebased against origin/master and there are many small commits. I don't actually know what's the policy on merging such a major branch from a non-committer[1]: should I rebase, squash, or preserve the history? Does anyone know? I also don't know if Philipp, who has many changes in that branch, has signed the contributor papers. Thanks Ted [1] I know Aurélien asked for the commit permissions on Savannah but I'm working with today's state :) ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-09 11:46 ` Ted Zlatanov @ 2015-11-09 12:27 ` Aurélien Aptel 2015-11-09 13:18 ` Steinar Bang 2015-11-09 13:38 ` Ted Zlatanov 0 siblings, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-11-09 12:27 UTC (permalink / raw) To: Emacs development discussions On Mon, Nov 9, 2015 at 12:46 PM, Ted Zlatanov <tzz@lifelogs.com> wrote: > I checked this branch: `git fetch git@github.com:aaptel/emacs-dynamic-module.git dynamic-modules-2`? Correct > It's not been rebased against origin/master and there are many small > commits. I don't actually know what's the policy on merging such a major > branch from a non-committer[1]: should I rebase, squash, or preserve the > history? Does anyone know? Whatever you do, I don't think its useful to preserve the history of my branch. I would suggest maybe splitting commits for the most invasive changes (throw/signal, Fload/load-suffixes, new user_ptr type) and import the completely new stuff in a single commit (all the content of modules/ basically). I know Philip tried to write Changelog entries for some commits in the commit message that can be re-used. If can try to make a new branch that can be re-based on master with the commits I had in mind if you want. > I also don't know if Philipp, who has many changes in that branch, has > signed the contributor papers. I thought he did, but I cannot find any commits on master from him so I guess he didn't. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-09 12:27 ` Aurélien Aptel @ 2015-11-09 13:18 ` Steinar Bang 2015-11-09 13:47 ` Steinar Bang 2015-11-09 13:38 ` Ted Zlatanov 1 sibling, 1 reply; 765+ messages in thread From: Steinar Bang @ 2015-11-09 13:18 UTC (permalink / raw) To: emacs-devel >>>>> Aurélien Aptel <aurelien.aptel+emacs@gmail.com>: > Whatever you do, I don't think its useful to preserve the history of > my branch. I would suggest maybe splitting commits for the most > invasive changes (throw/signal, Fload/load-suffixes, new user_ptr > type) and import the completely new stuff in a single commit (all the > content of modules/ basically). I know Philip tried to write Changelog > entries for some commits in the commit message that can be re-used. If > can try to make a new branch that can be re-based on master with the > commits I had in mind if you want. If Ted is going to do the job he has basically two choices: - Preserve all history of the branch - Squash all history of the branch into a single commit Everything else will be too hard, I think. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-09 13:18 ` Steinar Bang @ 2015-11-09 13:47 ` Steinar Bang 2015-11-09 14:26 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Steinar Bang @ 2015-11-09 13:47 UTC (permalink / raw) To: emacs-devel >>>>> Steinar Bang <sb@dod.no>: > If Ted is going to do the job he has basically two choices: > - Preserve all history of the branch > - Squash all history of the branch into a single commit (And I personally wouldn't have tried squashing after I have merged in from master) ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-09 13:47 ` Steinar Bang @ 2015-11-09 14:26 ` Aurélien Aptel 2015-11-09 14:52 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-11-09 14:26 UTC (permalink / raw) To: Emacs development discussions On Mon, Nov 9, 2015 at 2:47 PM, Steinar Bang <sb@dod.no> wrote: >> If Ted is going to do the job he has basically two choices: >> - Preserve all history of the branch >> - Squash all history of the branch into a single commit > > (And I personally wouldn't have tried squashing after I have merged in > from master) After merging master in the branch i can simply use a diff between the 2 (which shouldnt include conflicting/redundant changes this time) as what I'll use to make the new clean branch. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-09 14:26 ` Aurélien Aptel @ 2015-11-09 14:52 ` Aurélien Aptel 2015-11-09 19:58 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-11-09 14:52 UTC (permalink / raw) To: Emacs development discussions On Mon, Nov 9, 2015 at 3:26 PM, Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: > After merging master in the branch i can simply use a diff between the > 2 (which shouldnt include conflicting/redundant changes this time) as > what I'll use to make the new clean branch. So assuming master was successfully merged in dynamic-modules-2: git diff master dynamic-modules-2 > dyn.patch git checkout -b dynamic-modules-3 master git apply dyn.patch # now make a series of commit splitted in a way that makes sense git add -p FILE.. git commit etc. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-09 14:52 ` Aurélien Aptel @ 2015-11-09 19:58 ` Aurélien Aptel 2015-11-10 20:07 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-11-09 19:58 UTC (permalink / raw) To: Emacs development discussions, Ted Zlatanov I've made a clean new branch 'dynamic-modules-clean-1' on top of a recent master which you should be able to rebase easily. I've split my "working" branch into 6 Changelog-ready commits. I'm the author of the commits but a significant part of the code was also written by Philip Stefani (big thanks to him). Don't really know how to we can reflect that since it's all mixed up now. It's on github. You can rework the commit messages if you want as I'm not very good at this. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-09 19:58 ` Aurélien Aptel @ 2015-11-10 20:07 ` Philipp Stephani 0 siblings, 0 replies; 765+ messages in thread From: Philipp Stephani @ 2015-11-10 20:07 UTC (permalink / raw) To: Aurélien Aptel, Emacs development discussions, Ted Zlatanov [-- Attachment #1: Type: text/plain, Size: 341 bytes --] Aurélien Aptel <aurelien.aptel+emacs@gmail.com> schrieb am Mo., 9. Nov. 2015 um 20:59 Uhr: > I've made a clean new branch 'dynamic-modules-clean-1' on top of a > recent master which you should be able to rebase easily. Thanks! Since the freeze is only days away, can we now start merging these changes into the Savannah master? [-- Attachment #2: Type: text/html, Size: 629 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-09 12:27 ` Aurélien Aptel 2015-11-09 13:18 ` Steinar Bang @ 2015-11-09 13:38 ` Ted Zlatanov 2015-11-09 16:16 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Ted Zlatanov @ 2015-11-09 13:38 UTC (permalink / raw) To: emacs-devel On Mon, 9 Nov 2015 13:27:00 +0100 Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: AA> On Mon, Nov 9, 2015 at 12:46 PM, Ted Zlatanov <tzz@lifelogs.com> wrote: >> I checked this branch: `git fetch git@github.com:aaptel/emacs-dynamic-module.git dynamic-modules-2`? AA> Correct >> It's not been rebased against origin/master and there are many small >> commits. I don't actually know what's the policy on merging such a major >> branch from a non-committer[1]: should I rebase, squash, or preserve the >> history? Does anyone know? AA> Whatever you do, I don't think its useful to preserve the history of AA> my branch. I would suggest maybe splitting commits for the most AA> invasive changes (throw/signal, Fload/load-suffixes, new user_ptr AA> type) and import the completely new stuff in a single commit (all the AA> content of modules/ basically). I know Philip tried to write Changelog AA> entries for some commits in the commit message that can be re-used. If AA> can try to make a new branch that can be re-based on master with the AA> commits I had in mind if you want. Yes, please go ahead if you can. You know best which commits are "milestones" and which are not worth preserving. The rebasing can be part of your work. >> I also don't know if Philipp, who has many changes in that branch, has >> signed the contributor papers. AA> I thought he did, but I cannot find any commits on master from him so AA> I guess he didn't. That could be a problem, unfortunately. Let's wait for Philipp to comment. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-09 13:38 ` Ted Zlatanov @ 2015-11-09 16:16 ` Philipp Stephani 2015-11-11 11:22 ` Ted Zlatanov 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-09 16:16 UTC (permalink / raw) To: emacs-devel [-- Attachment #1: Type: text/plain, Size: 749 bytes --] Ted Zlatanov <tzz@lifelogs.com> schrieb am Mo., 9. Nov. 2015 um 14:38 Uhr: > On Mon, 9 Nov 2015 13:27:00 +0100 Aurélien Aptel < > aurelien.aptel+emacs@gmail.com> wrote: > > > >> I also don't know if Philipp, who has many changes in that branch, has > >> signed the contributor papers. > > AA> I thought he did, but I cannot find any commits on master from him so > AA> I guess he didn't. > > That could be a problem, unfortunately. Let's wait for Philipp to > comment. > > I don't need to sign the papers because my employer (Google) has a special agreement with the FSF. Please use my work address phst@google.com and "Copyright Google Inc." for my contributions. I already have a few patches in master under that address. [-- Attachment #2: Type: text/html, Size: 1207 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-09 16:16 ` Philipp Stephani @ 2015-11-11 11:22 ` Ted Zlatanov 2015-11-11 13:57 ` Philipp Stephani 2015-11-13 1:29 ` Aurélien Aptel 0 siblings, 2 replies; 765+ messages in thread From: Ted Zlatanov @ 2015-11-11 11:22 UTC (permalink / raw) To: emacs-devel On Mon, 09 Nov 2015 16:16:31 +0000 Philipp Stephani <p.stephani2@gmail.com> wrote: PS> I don't need to sign the papers because my employer (Google) has a special PS> agreement with the FSF. Please use my work address phst@google.com and PS> "Copyright Google Inc." for my contributions. I already have a few patches PS> in master under that address. Thank you. I can see that your existing patches didn't need the "Copyright Google Inc." in the commit message, so I think we can skip it here. On Mon, 9 Nov 2015 20:58:59 +0100 Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: AA> I've made a clean new branch 'dynamic-modules-clean-1' on top of a AA> recent master which you should be able to rebase easily. I've split my AA> "working" branch into 6 Changelog-ready commits. I'm the author of the AA> commits but a significant part of the code was also written by Philip AA> Stefani (big thanks to him). Don't really know how to we can reflect AA> that since it's all mixed up now. AA> It's on github. You can rework the commit messages if you want as I'm AA> not very good at this. Aurélien, it looks great. Thank you for the work. I have only two requests before I merge: 1) Can you add this header line to the commits that need it (it may require some checking, unfortunately): Co-authored-by: Philipp Stephani <phst@google.com> I *think* that's sufficient. 2) Since you're modifying some commits, can you remove the final period from the first line? It's a suggestion in CONTRIBUTE but not required. Otherwise I think it's ready to merge. On Tue, 10 Nov 2015 20:07:36 +0000 Philipp Stephani <p.stephani2@gmail.com> wrote: PS> Thanks! Since the freeze is only days away, can we now start merging these PS> changes into the Savannah master? Yes, I'll do the merge as soon as (1) above is resolved. Technically the patch looks good. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-11 11:22 ` Ted Zlatanov @ 2015-11-11 13:57 ` Philipp Stephani 2015-11-13 1:29 ` Aurélien Aptel 1 sibling, 0 replies; 765+ messages in thread From: Philipp Stephani @ 2015-11-11 13:57 UTC (permalink / raw) To: emacs-devel [-- Attachment #1: Type: text/plain, Size: 2113 bytes --] Ted Zlatanov <tzz@lifelogs.com> schrieb am Mi., 11. Nov. 2015 um 12:22 Uhr: > On Mon, 09 Nov 2015 16:16:31 +0000 Philipp Stephani <p.stephani2@gmail.com> > wrote: > > PS> I don't need to sign the papers because my employer (Google) has a > special > PS> agreement with the FSF. Please use my work address phst@google.com and > PS> "Copyright Google Inc." for my contributions. I already have a few > patches > PS> in master under that address. > > Thank you. I can see that your existing patches didn't need the > "Copyright Google Inc." in the commit message, so I think we can skip it > here. > > On Mon, 9 Nov 2015 20:58:59 +0100 Aurélien Aptel < > aurelien.aptel+emacs@gmail.com> wrote: > > AA> I've made a clean new branch 'dynamic-modules-clean-1' on top of a > AA> recent master which you should be able to rebase easily. I've split my > AA> "working" branch into 6 Changelog-ready commits. I'm the author of the > AA> commits but a significant part of the code was also written by Philip > AA> Stefani (big thanks to him). Don't really know how to we can reflect > AA> that since it's all mixed up now. > > AA> It's on github. You can rework the commit messages if you want as I'm > AA> not very good at this. > > Aurélien, it looks great. Thank you for the work. > > I have only two requests before I merge: > > 1) Can you add this header line to the commits that need it (it may > require some checking, unfortunately): > > Co-authored-by: Philipp Stephani <phst@google.com> > > I *think* that's sufficient. > > 2) Since you're modifying some commits, can you remove the final period > from the first line? It's a suggestion in CONTRIBUTE but not required. > > Otherwise I think it's ready to merge. > > On Tue, 10 Nov 2015 20:07:36 +0000 Philipp Stephani <p.stephani2@gmail.com> > wrote: > > PS> Thanks! Since the freeze is only days away, can we now start merging > these > PS> changes into the Savannah master? > > Yes, I'll do the merge as soon as (1) above is resolved. Technically the > patch looks good. > > Wonderful, thanks a lot! [-- Attachment #2: Type: text/html, Size: 2920 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-11 11:22 ` Ted Zlatanov 2015-11-11 13:57 ` Philipp Stephani @ 2015-11-13 1:29 ` Aurélien Aptel 2015-11-13 11:35 ` Ted Zlatanov 2015-11-16 0:10 ` Dynamic loading progress Aurélien Aptel 1 sibling, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-11-13 1:29 UTC (permalink / raw) To: Emacs development discussions Ted, we're still working some things out on github. Hopefully I can give a v2 merge-ready branch by this weekend. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-13 1:29 ` Aurélien Aptel @ 2015-11-13 11:35 ` Ted Zlatanov 2015-11-13 15:39 ` Freeze is almost here (was: Dynamic loading progress) John Wiegley 2015-11-16 0:10 ` Dynamic loading progress Aurélien Aptel 1 sibling, 1 reply; 765+ messages in thread From: Ted Zlatanov @ 2015-11-13 11:35 UTC (permalink / raw) To: emacs-devel On Fri, 13 Nov 2015 02:29:09 +0100 Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: AA> Ted, we're still working some things out on github. Hopefully I can AA> give a v2 merge-ready branch by this weekend. John, can the dynamic modules branch be pushed then or do you need it today? I'm OK with the delay. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Freeze is almost here (was: Dynamic loading progress) 2015-11-13 11:35 ` Ted Zlatanov @ 2015-11-13 15:39 ` John Wiegley 2015-11-13 16:43 ` Juanma Barranquero ` (2 more replies) 0 siblings, 3 replies; 765+ messages in thread From: John Wiegley @ 2015-11-13 15:39 UTC (permalink / raw) To: emacs-devel >>>>> Ted Zlatanov <tzz@lifelogs.com> writes: > John, can the dynamic modules branch be pushed then or do you need it today? > I'm OK with the delay. Sure, it can be pushed then. In fact, anytime next week is OK for that branch. I've created the "emacs-25" branch, and will merge from master one last time in 8.4 hours. After that, only bug fixes should be applied to that branch, or feature work for those with an exemption. I encourage everyone without pressing feature work to make that branch their primary working area for the next few months, and to help me categorize the bugs appropriately. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here (was: Dynamic loading progress) 2015-11-13 15:39 ` Freeze is almost here (was: Dynamic loading progress) John Wiegley @ 2015-11-13 16:43 ` Juanma Barranquero 2015-11-13 19:24 ` Eli Zaretskii 2015-11-14 0:56 ` Freeze is almost here (was: Dynamic loading progress) Xue Fuqiao 2 siblings, 0 replies; 765+ messages in thread From: Juanma Barranquero @ 2015-11-13 16:43 UTC (permalink / raw) To: Emacs developers [-- Attachment #1: Type: text/plain, Size: 198 bytes --] On Fri, Nov 13, 2015 at 4:39 PM, John Wiegley <jwiegley@gmail.com> wrote: > After that, only bug fixes should be applied to that branch, or > feature work for those with an exemption. Or tests... [-- Attachment #2: Type: text/html, Size: 324 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here (was: Dynamic loading progress) 2015-11-13 15:39 ` Freeze is almost here (was: Dynamic loading progress) John Wiegley 2015-11-13 16:43 ` Juanma Barranquero @ 2015-11-13 19:24 ` Eli Zaretskii 2015-11-13 19:37 ` Eli Zaretskii 2015-11-14 0:56 ` Freeze is almost here (was: Dynamic loading progress) Xue Fuqiao 2 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-13 19:24 UTC (permalink / raw) To: John Wiegley; +Cc: emacs-devel > From: John Wiegley <jwiegley@gmail.com> > Date: Fri, 13 Nov 2015 07:39:27 -0800 > > >>>>> Ted Zlatanov <tzz@lifelogs.com> writes: > > > John, can the dynamic modules branch be pushed then or do you need it today? > > I'm OK with the delay. > > Sure, it can be pushed then. In fact, anytime next week is OK for that branch. > > I've created the "emacs-25" branch, and will merge from master one last time > in 8.4 hours. After that, only bug fixes should be applied to that branch, or > feature work for those with an exemption. We don't merge from master to the release branch, we merge in the opposite direction. See gitmerge.el. So I think the dynamic modules changes should be applied to emacs-25, and will then be merged to master in due time. > I encourage everyone without pressing feature work to make that branch their > primary working area for the next few months, and to help me categorize the > bugs appropriately. Seconded. in any case, once the release branch is cut, any bugfixes that fix problems visible on emacs-25 should be applied there, not to master (they will be later merged to master via gitmerge.el). The master branch should only get direct commits of fixes for bugs that don't exist on the release branch. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here (was: Dynamic loading progress) 2015-11-13 19:24 ` Eli Zaretskii @ 2015-11-13 19:37 ` Eli Zaretskii 2015-11-13 20:05 ` Freeze is almost here Achim Gratz ` (2 more replies) 0 siblings, 3 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-13 19:37 UTC (permalink / raw) To: Eli Zaretskii; +Cc: jwiegley, emacs-devel > Date: Fri, 13 Nov 2015 21:24:36 +0200 > From: Eli Zaretskii <eliz@gnu.org> > Cc: emacs-devel@gnu.org > > We don't merge from master to the release branch, we merge in the > opposite direction. See gitmerge.el. So I think the dynamic modules > changes should be applied to emacs-25, and will then be merged to > master in due time. I see that you branched emacs-25 not from the latest master. This means all the commits since 9463abf will have to be cherry-picked from master to the emacs-25 branch. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-13 19:37 ` Eli Zaretskii @ 2015-11-13 20:05 ` Achim Gratz 2015-11-13 20:17 ` Eli Zaretskii 2015-11-13 20:05 ` Freeze is almost here (was: Dynamic loading progress) Eli Zaretskii 2015-11-13 21:34 ` Andreas Schwab 2 siblings, 1 reply; 765+ messages in thread From: Achim Gratz @ 2015-11-13 20:05 UTC (permalink / raw) To: emacs-devel Eli Zaretskii writes: > I see that you branched emacs-25 not from the latest master. This > means all the commits since 9463abf will have to be cherry-picked from > master to the emacs-25 branch. That's likely why John plans to merge master into the release branch again at some later time. This postpones the actual freeze and avoids the superfluous cherry-picks. Regards, Achim. -- +<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+ Factory and User Sound Singles for Waldorf Blofeld: http://Synth.Stromeko.net/Downloads.html#WaldorfSounds ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-13 20:05 ` Freeze is almost here Achim Gratz @ 2015-11-13 20:17 ` Eli Zaretskii 2015-11-13 20:36 ` Achim Gratz ` (2 more replies) 0 siblings, 3 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-13 20:17 UTC (permalink / raw) To: Achim Gratz; +Cc: emacs-devel > From: Achim Gratz <Stromeko@nexgo.de> > Date: Fri, 13 Nov 2015 21:05:14 +0100 > > Eli Zaretskii writes: > > I see that you branched emacs-25 not from the latest master. This > > means all the commits since 9463abf will have to be cherry-picked from > > master to the emacs-25 branch. > > That's likely why John plans to merge master into the release branch > again at some later time. This postpones the actual freeze and avoids > the superfluous cherry-picks. Merging from master to the release branch will likely make a mess when we later merge back the bugfixes. Anyway, I already pushed all the cherry-picks (with a special marker that should exempt them from merging back via gitmerge.el). ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-13 20:17 ` Eli Zaretskii @ 2015-11-13 20:36 ` Achim Gratz 2015-11-13 20:46 ` Eli Zaretskii 2015-11-13 21:46 ` Dmitry Gutov 2015-11-14 11:27 ` Artur Malabarba 2 siblings, 1 reply; 765+ messages in thread From: Achim Gratz @ 2015-11-13 20:36 UTC (permalink / raw) To: emacs-devel Eli Zaretskii writes: > Merging from master to the release branch will likely make a mess when > we later merge back the bugfixes. No, not any more than merging master multiple times into a feature branch does before you push it back to master. Regards, Achim. -- +<[Q+ Matrix-12 WAVE#46+305 Neuron microQkb Andromeda XTk Blofeld]>+ SD adaptation for Waldorf rackAttack V1.04R1: http://Synth.Stromeko.net/Downloads.html#WaldorfSDada ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-13 20:36 ` Achim Gratz @ 2015-11-13 20:46 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-13 20:46 UTC (permalink / raw) To: Achim Gratz; +Cc: emacs-devel > From: Achim Gratz <Stromeko@nexgo.de> > Date: Fri, 13 Nov 2015 21:36:59 +0100 > > Eli Zaretskii writes: > > Merging from master to the release branch will likely make a mess when > > we later merge back the bugfixes. > > No, not any more than merging master multiple times into a feature > branch does before you push it back to master. Which indeed makes a mess, see "git log --graph" on master. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-13 20:17 ` Eli Zaretskii 2015-11-13 20:36 ` Achim Gratz @ 2015-11-13 21:46 ` Dmitry Gutov 2015-11-14 11:27 ` Artur Malabarba 2 siblings, 0 replies; 765+ messages in thread From: Dmitry Gutov @ 2015-11-13 21:46 UTC (permalink / raw) To: Eli Zaretskii, Achim Gratz; +Cc: emacs-devel On 11/13/2015 10:17 PM, Eli Zaretskii wrote: > Merging from master to the release branch will likely make a mess when > we later merge back the bugfixes. Like others mentioned, not at all. > Anyway, I already pushed all the cherry-picks (with a special marker > that should exempt them from merging back via gitmerge.el). Yeah, that was premature. John was clearly planning a fast-forward merge from master later today. On the other hand, I don't know why we needed emacs-25 to be created in advance. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-13 20:17 ` Eli Zaretskii 2015-11-13 20:36 ` Achim Gratz 2015-11-13 21:46 ` Dmitry Gutov @ 2015-11-14 11:27 ` Artur Malabarba 2015-11-14 11:55 ` Eli Zaretskii 2015-11-14 17:08 ` Dmitry Gutov 2 siblings, 2 replies; 765+ messages in thread From: Artur Malabarba @ 2015-11-14 11:27 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel 2015-11-13 20:17 GMT+00:00 Eli Zaretskii <eliz@gnu.org>: > Anyway, I already pushed all the cherry-picks (with a special marker > that should exempt them from merging back via gitmerge.el). What is the marker you use? I need to do push a commit to emacs-25 that is not to be merged back to master. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 11:27 ` Artur Malabarba @ 2015-11-14 11:55 ` Eli Zaretskii 2015-11-14 12:34 ` Artur Malabarba 2015-11-14 17:08 ` Dmitry Gutov 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-14 11:55 UTC (permalink / raw) To: bruce.connor.am; +Cc: emacs-devel > Date: Sat, 14 Nov 2015 11:27:48 +0000 > From: Artur Malabarba <bruce.connor.am@gmail.com> > Cc: emacs-devel <emacs-devel@gnu.org> > > 2015-11-13 20:17 GMT+00:00 Eli Zaretskii <eliz@gnu.org>: > > Anyway, I already pushed all the cherry-picks (with a special marker > > that should exempt them from merging back via gitmerge.el). > > What is the marker you use? "Backport". This is described in CONTRIBUTE; I just made it a tad more clear. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 11:55 ` Eli Zaretskii @ 2015-11-14 12:34 ` Artur Malabarba 0 siblings, 0 replies; 765+ messages in thread From: Artur Malabarba @ 2015-11-14 12:34 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel 2015-11-14 11:55 GMT+00:00 Eli Zaretskii <eliz@gnu.org>: >> Date: Sat, 14 Nov 2015 11:27:48 +0000 >> From: Artur Malabarba <bruce.connor.am@gmail.com> >> Cc: emacs-devel <emacs-devel@gnu.org> >> >> 2015-11-13 20:17 GMT+00:00 Eli Zaretskii <eliz@gnu.org>: >> > Anyway, I already pushed all the cherry-picks (with a special marker >> > that should exempt them from merging back via gitmerge.el). >> >> What is the marker you use? > > "Backport". This is described in CONTRIBUTE; I just made it a tad > more clear. Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 11:27 ` Artur Malabarba 2015-11-14 11:55 ` Eli Zaretskii @ 2015-11-14 17:08 ` Dmitry Gutov 1 sibling, 0 replies; 765+ messages in thread From: Dmitry Gutov @ 2015-11-14 17:08 UTC (permalink / raw) To: bruce.connor.am, Eli Zaretskii; +Cc: emacs-devel On 11/14/2015 01:27 PM, Artur Malabarba wrote: > What is the marker you use? I need to do push a commit to emacs-25 > that is not to be merged back to master. As you can see, each of those cherry-picked commits has "Backport" in its message. For other possible markers, see gitmerge-skip-regexp in admin/gitmerge.el. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here (was: Dynamic loading progress) 2015-11-13 19:37 ` Eli Zaretskii 2015-11-13 20:05 ` Freeze is almost here Achim Gratz @ 2015-11-13 20:05 ` Eli Zaretskii 2015-11-13 20:31 ` Eli Zaretskii 2015-11-13 21:34 ` Andreas Schwab 2 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-13 20:05 UTC (permalink / raw) To: jwiegley; +Cc: emacs-devel > Date: Fri, 13 Nov 2015 21:37:53 +0200 > From: Eli Zaretskii <eliz@gnu.org> > Cc: jwiegley@gmail.com, emacs-devel@gnu.org > > I see that you branched emacs-25 not from the latest master. This > means all the commits since 9463abf will have to be cherry-picked from > master to the emacs-25 branch. Done. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here (was: Dynamic loading progress) 2015-11-13 20:05 ` Freeze is almost here (was: Dynamic loading progress) Eli Zaretskii @ 2015-11-13 20:31 ` Eli Zaretskii 2015-11-13 22:57 ` Freeze is almost here John Wiegley 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-13 20:31 UTC (permalink / raw) To: jwiegley; +Cc: emacs-devel > Date: Fri, 13 Nov 2015 22:05:47 +0200 > From: Eli Zaretskii <eliz@gnu.org> > Cc: emacs-devel@gnu.org > > > Date: Fri, 13 Nov 2015 21:37:53 +0200 > > From: Eli Zaretskii <eliz@gnu.org> > > Cc: jwiegley@gmail.com, emacs-devel@gnu.org > > > > I see that you branched emacs-25 not from the latest master. This > > means all the commits since 9463abf will have to be cherry-picked from > > master to the emacs-25 branch. > > Done. We should now change master to identify itself as version 25.1.50 or maybe even 26.0.50. OK? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-13 20:31 ` Eli Zaretskii @ 2015-11-13 22:57 ` John Wiegley 2015-11-14 8:42 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: John Wiegley @ 2015-11-13 22:57 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel >>>>> Eli Zaretskii <eliz@gnu.org> writes: > We should now change master to identify itself as version 25.1.50 or maybe > even 26.0.50. OK? Let's go with 25.1.50 for now. Next time we'll coordinate better to avoid the cherry-picking. The merge commit you'll see today is because I didn't read these messages until after doing it, but it should have had very little impact. We also have about 12 commits of replicated history, but that's the price of learning. FWIW, I don't believe "directionality" matters to Git, until you have changes on one branch you don't ever want to see on another. Since the freeze hadn't happened yet, it should have been OK to unify the branches in either direction. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-13 22:57 ` Freeze is almost here John Wiegley @ 2015-11-14 8:42 ` Eli Zaretskii 2015-11-14 15:59 ` John Wiegley 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-14 8:42 UTC (permalink / raw) To: John Wiegley; +Cc: emacs-devel > From: John Wiegley <jwiegley@gmail.com> > Cc: emacs-devel@gnu.org > Date: Fri, 13 Nov 2015 14:57:56 -0800 > > >>>>> Eli Zaretskii <eliz@gnu.org> writes: > > > We should now change master to identify itself as version 25.1.50 or maybe > > even 26.0.50. OK? > > Let's go with 25.1.50 for now. Done. > FWIW, I don't believe "directionality" matters to Git It matters to us, though. > until you have changes on one branch you don't ever want to see on > another. Since the freeze hadn't happened yet, it should have been > OK to unify the branches in either direction. I don't understand how freeze is relevant to this. Or maybe I don't understand what "freeze" means in terms of Git operations. Can you explain? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 8:42 ` Eli Zaretskii @ 2015-11-14 15:59 ` John Wiegley 2015-11-15 9:53 ` Steinar Bang 0 siblings, 1 reply; 765+ messages in thread From: John Wiegley @ 2015-11-14 15:59 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Emacs Development >>>>> Eli Zaretskii <eliz@gnu.org> writes: >> FWIW, I don't believe "directionality" matters to Git > It matters to us, though. All I meant is that until the actual freeze, master and emacs-25 were equivalent. Now they no longer are. I'm sorry to have created so much confusion, I assumed too much about our collective Git habits. Next time I'll "cut once", and it will be frozen from that moment forward. I had feared I wouldn't be available to do it at the right time, so I did it early, expecting to allow changes from master until the cutoff point. Now that all that's done, we're back on the right footing. I'll make a wider announcement later today. Thanks for your patience, Eli, John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 15:59 ` John Wiegley @ 2015-11-15 9:53 ` Steinar Bang 2015-11-16 9:28 ` Steinar Bang 2015-11-16 16:54 ` John Wiegley 0 siblings, 2 replies; 765+ messages in thread From: Steinar Bang @ 2015-11-15 9:53 UTC (permalink / raw) To: emacs-devel >>>>> "John Wiegley" <jwiegley@gmail.com>: > I'm sorry to have created so much confusion, I assumed too much about our > collective Git habits. Next time I'll "cut once", and it will be frozen from > that moment forward. I had feared I wouldn't be available to do it at the > right time, so I did it early, expecting to allow changes from master until > the cutoff point. Note that you can branch off from any commit on master after the fact. Ie. you can look down the history list of master and decide "Ah! There!", and then do git checkout -b emacs-26.1 <sha1-has-of-the-commit-where-the-branch-should-start> git push -u origin HEAD ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-15 9:53 ` Steinar Bang @ 2015-11-16 9:28 ` Steinar Bang 2015-11-16 16:54 ` John Wiegley 1 sibling, 0 replies; 765+ messages in thread From: Steinar Bang @ 2015-11-16 9:28 UTC (permalink / raw) To: emacs-devel >>>>> Steinar Bang <sb@dod.no>: >>>>> "John Wiegley" <jwiegley@gmail.com>: >> I'm sorry to have created so much confusion, I assumed too much about our >> collective Git habits. Next time I'll "cut once", and it will be frozen from >> that moment forward. I had feared I wouldn't be available to do it at the >> right time, so I did it early, expecting to allow changes from master until >> the cutoff point. > Note that you can branch off from any commit on master after the fact. > Ie. you can look down the history list of master and decide "Ah! > There!", and then do > git checkout -b emacs-26.1 <sha1-has-of-the-commit-where-the-branch-should-start> > git push -u origin HEAD (note: my use of "emacs-26.1" as an example is for the next release branch off master. "emacs-25" is already a done deal) ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-15 9:53 ` Steinar Bang 2015-11-16 9:28 ` Steinar Bang @ 2015-11-16 16:54 ` John Wiegley 1 sibling, 0 replies; 765+ messages in thread From: John Wiegley @ 2015-11-16 16:54 UTC (permalink / raw) To: emacs-devel >>>>> Steinar Bang <sb@dod.no> writes: > Note that you can branch off from any commit on master after the fact. Ie. > you can look down the history list of master and decide "Ah! There!", and > then do git checkout -b emacs-26.1 > <sha1-has-of-the-commit-where-the-branch-should-start> git push -u origin > HEAD That is such a good point, thanks Steinar. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-13 19:37 ` Eli Zaretskii 2015-11-13 20:05 ` Freeze is almost here Achim Gratz 2015-11-13 20:05 ` Freeze is almost here (was: Dynamic loading progress) Eli Zaretskii @ 2015-11-13 21:34 ` Andreas Schwab 2015-11-14 8:03 ` Eli Zaretskii 2 siblings, 1 reply; 765+ messages in thread From: Andreas Schwab @ 2015-11-13 21:34 UTC (permalink / raw) To: Eli Zaretskii; +Cc: jwiegley, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > I see that you branched emacs-25 not from the latest master. This > means all the commits since 9463abf will have to be cherry-picked from > master to the emacs-25 branch. ??? Just fast forward it. Andreas. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-13 21:34 ` Andreas Schwab @ 2015-11-14 8:03 ` Eli Zaretskii 2015-11-14 8:16 ` Andreas Schwab 2015-11-14 8:45 ` David Engster 0 siblings, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-14 8:03 UTC (permalink / raw) To: Andreas Schwab; +Cc: jwiegley, emacs-devel > From: Andreas Schwab <schwab@linux-m68k.org> > Cc: jwiegley@gmail.com, emacs-devel@gnu.org > Date: Fri, 13 Nov 2015 22:34:50 +0100 > > Eli Zaretskii <eliz@gnu.org> writes: > > > I see that you branched emacs-25 not from the latest master. This > > means all the commits since 9463abf will have to be cherry-picked from > > master to the emacs-25 branch. > > ??? Just fast forward it. I didn't know how to do that (can you tell?). In any case, by the time I got to that, someone already made one commit to the branch, so I think fast-forwarding would have been impossible. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 8:03 ` Eli Zaretskii @ 2015-11-14 8:16 ` Andreas Schwab 2015-11-14 8:27 ` Eli Zaretskii 2015-11-14 8:45 ` David Engster 1 sibling, 1 reply; 765+ messages in thread From: Andreas Schwab @ 2015-11-14 8:16 UTC (permalink / raw) To: Eli Zaretskii; +Cc: jwiegley, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Andreas Schwab <schwab@linux-m68k.org> >> Cc: jwiegley@gmail.com, emacs-devel@gnu.org >> Date: Fri, 13 Nov 2015 22:34:50 +0100 >> >> Eli Zaretskii <eliz@gnu.org> writes: >> >> > I see that you branched emacs-25 not from the latest master. This >> > means all the commits since 9463abf will have to be cherry-picked from >> > master to the emacs-25 branch. >> >> ??? Just fast forward it. > > I didn't know how to do that (can you tell?). git merge > In any case, by the time I got to that, someone already made one > commit to the branch, so I think fast-forwarding would have been > impossible. No, there is no such commit. Andreas. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 8:16 ` Andreas Schwab @ 2015-11-14 8:27 ` Eli Zaretskii 2015-11-14 10:06 ` Andreas Schwab 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-14 8:27 UTC (permalink / raw) To: Andreas Schwab; +Cc: jwiegley, emacs-devel > From: Andreas Schwab <schwab@linux-m68k.org> > Cc: jwiegley@gmail.com, emacs-devel@gnu.org > Date: Sat, 14 Nov 2015 09:16:40 +0100 > > Eli Zaretskii <eliz@gnu.org> writes: > > >> ??? Just fast forward it. > > > > I didn't know how to do that (can you tell?). > > git merge Right, thanks. > > In any case, by the time I got to that, someone already made one > > commit to the branch, so I think fast-forwarding would have been > > impossible. > > No, there is no such commit. AFAIU, there is: 26e7624b234f350a1f483d6fe0be8c30cca03008. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 8:27 ` Eli Zaretskii @ 2015-11-14 10:06 ` Andreas Schwab 0 siblings, 0 replies; 765+ messages in thread From: Andreas Schwab @ 2015-11-14 10:06 UTC (permalink / raw) To: Eli Zaretskii; +Cc: jwiegley, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: > AFAIU, there is: 26e7624b234f350a1f483d6fe0be8c30cca03008. Right, I missed that. Andreas. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 8:03 ` Eli Zaretskii 2015-11-14 8:16 ` Andreas Schwab @ 2015-11-14 8:45 ` David Engster 2015-11-14 9:15 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: David Engster @ 2015-11-14 8:45 UTC (permalink / raw) To: Eli Zaretskii; +Cc: jwiegley, Andreas Schwab, emacs-devel Eli Zaretskii writes: >> From: Andreas Schwab <schwab@linux-m68k.org> >> Cc: jwiegley@gmail.com, emacs-devel@gnu.org >> Date: Fri, 13 Nov 2015 22:34:50 +0100 > >> >> Eli Zaretskii <eliz@gnu.org> writes: >> >> > I see that you branched emacs-25 not from the latest master. This >> > means all the commits since 9463abf will have to be cherry-picked from >> > master to the emacs-25 branch. >> >> ??? Just fast forward it. > > I didn't know how to do that (can you tell?). By merging master into emacs-25. Git will do a fast-forward by default if it is possible (use --ff-only to abort otherwise). Regarding your 'Backport' messages in the cherry-picks: You only need to do that when there was a conflict. Otherwise, gitmerge.el should detect cherry-picks through the cherry-mark and automatically mark them as to be skipped. However, I realize now that I'm calling the wrong log command for that; I'll fix that over the weekend. -David ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 8:45 ` David Engster @ 2015-11-14 9:15 ` Eli Zaretskii 2015-11-14 12:54 ` David Engster 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-14 9:15 UTC (permalink / raw) To: David Engster; +Cc: jwiegley, schwab, emacs-devel > From: David Engster <deng@randomsample.de> > Cc: Andreas Schwab <schwab@linux-m68k.org>, jwiegley@gmail.com, emacs-devel@gnu.org > Date: Sat, 14 Nov 2015 09:45:10 +0100 > > >> ??? Just fast forward it. > > > > I didn't know how to do that (can you tell?). > > By merging master into emacs-25. Git will do a fast-forward by default > if it is possible (use --ff-only to abort otherwise). Thanks, will do in the future. > Regarding your 'Backport' messages in the cherry-picks: You only need to > do that when there was a conflict. Otherwise, gitmerge.el should detect > cherry-picks through the cherry-mark and automatically mark them as to > be skipped. However, I realize now that I'm calling the wrong log > command for that; I'll fix that over the weekend. Thanks. Please also consider whether we need some changes in gitmerge.el now that we produce ChangeLog from the Git log. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 9:15 ` Eli Zaretskii @ 2015-11-14 12:54 ` David Engster 2015-11-14 12:57 ` David Engster 2015-11-14 13:33 ` Eli Zaretskii 0 siblings, 2 replies; 765+ messages in thread From: David Engster @ 2015-11-14 12:54 UTC (permalink / raw) To: Eli Zaretskii; +Cc: jwiegley, schwab, emacs-devel Eli Zaretskii writes: >> From: David Engster <deng@randomsample.de> >> Cc: Andreas Schwab <schwab@linux-m68k.org>, jwiegley@gmail.com, >> emacs-devel@gnu.org > >> Date: Sat, 14 Nov 2015 09:45:10 +0100 >> Regarding your 'Backport' messages in the cherry-picks: You only need to >> do that when there was a conflict. Otherwise, gitmerge.el should detect >> cherry-picks through the cherry-mark and automatically mark them as to >> be skipped. However, I realize now that I'm calling the wrong log >> command for that; I'll fix that over the weekend. > > Thanks. > > Please also consider whether we need some changes in gitmerge.el now > that we produce ChangeLog from the Git log. I see now that master was merged into emacs-25. Is this now the new workflow? If so, there's not much point in keeping gitmerge.el anyway. -David ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 12:54 ` David Engster @ 2015-11-14 12:57 ` David Engster 2015-11-14 13:36 ` Eli Zaretskii 2015-11-14 13:33 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: David Engster @ 2015-11-14 12:57 UTC (permalink / raw) To: Eli Zaretskii; +Cc: jwiegley, schwab, emacs-devel David Engster writes: > I see now that master was merged into emacs-25. Is this now the new > workflow? If so, there's not much point in keeping gitmerge.el anyway. Sorry, forget what I said. I forgot the we don't freeze master anymore, so I guess this was a one-time merge just to forward emacs-25. I was just confused because git couldn't detect the cherry-picks, but this is because of this merge from master. -David ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 12:57 ` David Engster @ 2015-11-14 13:36 ` Eli Zaretskii 2015-11-14 14:37 ` David Engster 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-14 13:36 UTC (permalink / raw) To: David Engster; +Cc: jwiegley, schwab, emacs-devel > From: David Engster <deng@randomsample.de> > Cc: schwab@linux-m68k.org, jwiegley@gmail.com, emacs-devel@gnu.org > Date: Sat, 14 Nov 2015 13:57:34 +0100 > > David Engster writes: > > I see now that master was merged into emacs-25. Is this now the new > > workflow? If so, there's not much point in keeping gitmerge.el anyway. > > Sorry, forget what I said. I forgot the we don't freeze master anymore, > so I guess this was a one-time merge just to forward emacs-25. I was > just confused because git couldn't detect the cherry-picks, but this is > because of this merge from master. Could you describe the conditions necessary for gitmerge to detect cherry-picks? I see that it uses --cherry-mark, but would that mark cherry-picks whose commit message was edited by "cherry-pick -e"? (That editing is necessary to add "Backported", at least.) Also, what about the effect of the "cherry-pick -x" switch, does affect gitmerge in any way? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 13:36 ` Eli Zaretskii @ 2015-11-14 14:37 ` David Engster 2015-11-14 15:02 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: David Engster @ 2015-11-14 14:37 UTC (permalink / raw) To: Eli Zaretskii; +Cc: jwiegley, schwab, emacs-devel Eli Zaretskii writes: >> From: David Engster <deng@randomsample.de> >> Cc: schwab@linux-m68k.org, jwiegley@gmail.com, emacs-devel@gnu.org >> Date: Sat, 14 Nov 2015 13:57:34 +0100 > >> >> David Engster writes: >> > I see now that master was merged into emacs-25. Is this now the new >> > workflow? If so, there's not much point in keeping gitmerge.el anyway. >> >> Sorry, forget what I said. I forgot the we don't freeze master anymore, >> so I guess this was a one-time merge just to forward emacs-25. I was >> just confused because git couldn't detect the cherry-picks, but this is >> because of this merge from master. > > Could you describe the conditions necessary for gitmerge to detect > cherry-picks? I see that it uses --cherry-mark, but would that mark > cherry-picks whose commit message was edited by "cherry-pick -e"? Yes. Cherry-picks are detected through the "patch-id", which is not affected by the commit message but only by the diff (see 'git help patch-id'). This is why it's fine to change the commit message, but when you resolve a conflict, the patch-id will usually change. But when you later *merge* the branch from which you cherry-picked (like we did with 'master'), git of course sees the cherry-picked commits as merged, and hence does not check the patch-id later as well (most likely because that would be slow). At least that's how I understand it. > Also, what about the effect of the "cherry-pick -x" switch, does > affect gitmerge in any way? We could of course add "cherry picked" to the gitmerge-skip-regexp, but otherwise, the '-x' has no affect on how git itself detects cherry-picks. -David ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 14:37 ` David Engster @ 2015-11-14 15:02 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-14 15:02 UTC (permalink / raw) To: David Engster; +Cc: jwiegley, schwab, emacs-devel > From: David Engster <deng@randomsample.de> > Cc: schwab@linux-m68k.org, jwiegley@gmail.com, emacs-devel@gnu.org > Date: Sat, 14 Nov 2015 15:37:51 +0100 > > But when you later *merge* the branch from which you cherry-picked (like > we did with 'master'), git of course sees the cherry-picked commits as > merged, and hence does not check the patch-id later as well (most likely > because that would be slow). At least that's how I understand it. I hope we won't merge from master to emacs-25. > > Also, what about the effect of the "cherry-pick -x" switch, does > > affect gitmerge in any way? > > We could of course add "cherry picked" to the gitmerge-skip-regexp, but > otherwise, the '-x' has no affect on how git itself detects > cherry-picks. If detection of cherry-picks is reliable, I see no need to add that to gitmerge-skip-regexp. Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 12:54 ` David Engster 2015-11-14 12:57 ` David Engster @ 2015-11-14 13:33 ` Eli Zaretskii 2015-11-14 14:42 ` David Engster 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-14 13:33 UTC (permalink / raw) To: David Engster; +Cc: jwiegley, schwab, emacs-devel > From: David Engster <deng@randomsample.de> > Cc: schwab@linux-m68k.org, jwiegley@gmail.com, emacs-devel@gnu.org > Date: Sat, 14 Nov 2015 13:54:02 +0100 > > I see now that master was merged into emacs-25. Is this now the new > workflow? I hope not. I tried to prevent that, but evidently failed. Sorry. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 13:33 ` Eli Zaretskii @ 2015-11-14 14:42 ` David Engster 2015-11-14 15:01 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: David Engster @ 2015-11-14 14:42 UTC (permalink / raw) To: Eli Zaretskii; +Cc: jwiegley, schwab, emacs-devel Eli Zaretskii writes: >> From: David Engster <deng@randomsample.de> >> Cc: schwab@linux-m68k.org, jwiegley@gmail.com, emacs-devel@gnu.org >> Date: Sat, 14 Nov 2015 13:54:02 +0100 >> >> I see now that master was merged into emacs-25. Is this now the new >> workflow? > > I hope not. I tried to prevent that, but evidently failed. Well, I think everyone agrees that we cannot merge 'master' into 'emacs-25' as soon as we have commits 'master' that introduce new features. The problem is that everyone must know that bug fixes etc. should from now on land in 'emacs-25'. Didn't we have an 'announce' list for things like that? -David ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 14:42 ` David Engster @ 2015-11-14 15:01 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-14 15:01 UTC (permalink / raw) To: David Engster; +Cc: jwiegley, schwab, emacs-devel > From: David Engster <deng@randomsample.de> > Cc: schwab@linux-m68k.org, jwiegley@gmail.com, emacs-devel@gnu.org > Date: Sat, 14 Nov 2015 15:42:18 +0100 > > Well, I think everyone agrees that we cannot merge 'master' into > 'emacs-25' as soon as we have commits 'master' that introduce new > features. Yes, and I thought this rule starts as soon as emacs-25 branch was cut. > Didn't we have an 'announce' list for things like that? Not a list, a keyword: http://lists.gnu.org/archive/html/emacs-devel/2015-10/msg00062.html AFAIU, this means the message should have a "Keywords: emacs-announce" header, or have a "Keywords: emacs-announce" line in the first 5 lines of its body. Then list subscribers who specified they only want to get messages for that topic will receive such a message. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here (was: Dynamic loading progress) 2015-11-13 15:39 ` Freeze is almost here (was: Dynamic loading progress) John Wiegley 2015-11-13 16:43 ` Juanma Barranquero 2015-11-13 19:24 ` Eli Zaretskii @ 2015-11-14 0:56 ` Xue Fuqiao 2015-11-14 6:06 ` Freeze is almost here John Wiegley 2 siblings, 1 reply; 765+ messages in thread From: Xue Fuqiao @ 2015-11-14 0:56 UTC (permalink / raw) To: Emacs-devel On Fri, Nov 13, 2015 at 11:39 PM, John Wiegley <jwiegley@gmail.com> wrote: Hi John, > I encourage everyone without pressing feature work to make that branch their > primary working area for the next few months, and to help me categorize the > bugs appropriately. Will `master' will be frozen? If not, I'll make changes to my patch in the "Feature freezes and Emacs 25" thread. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 0:56 ` Freeze is almost here (was: Dynamic loading progress) Xue Fuqiao @ 2015-11-14 6:06 ` John Wiegley 2015-11-14 8:22 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: John Wiegley @ 2015-11-14 6:06 UTC (permalink / raw) To: Xue Fuqiao; +Cc: Emacs-devel >>>>> Xue Fuqiao <xfq.free@gmail.com> writes: > Will `master' will be frozen? If not, I'll make changes to my patch in the > "Feature freezes and Emacs 25" thread. Thanks for asking; to clarify: 'master' is not going to be frozen at any point. Rather, emacs-25 now represents the candidate for 25.1, and is where work should proceed for fixing bugs. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Freeze is almost here 2015-11-14 6:06 ` Freeze is almost here John Wiegley @ 2015-11-14 8:22 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-14 8:22 UTC (permalink / raw) To: John Wiegley; +Cc: xfq.free, emacs-devel > From: John Wiegley <jwiegley@gmail.com> > Date: Fri, 13 Nov 2015 22:06:43 -0800 > Cc: Emacs-devel <emacs-devel@gnu.org> > > >>>>> Xue Fuqiao <xfq.free@gmail.com> writes: > > > Will `master' will be frozen? If not, I'll make changes to my patch in the > > "Feature freezes and Emacs 25" thread. > > Thanks for asking; to clarify: 'master' is not going to be frozen at any > point. Rather, emacs-25 now represents the candidate for 25.1, and is where > work should proceed for fixing bugs. A further clarification, about documentation: documentation changes that are relevant to Emacs 25.1 should be committed to the emacs-25 branch, even if they don't technically "fix bugs". ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-13 1:29 ` Aurélien Aptel 2015-11-13 11:35 ` Ted Zlatanov @ 2015-11-16 0:10 ` Aurélien Aptel 2015-11-17 2:23 ` raman 2015-11-17 8:26 ` Steinar Bang 1 sibling, 2 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-11-16 0:10 UTC (permalink / raw) To: Emacs development discussions, Ted Zlatanov As promised, you can find a new merge-ready branch called dynamic-modules-clean-2 on my github repo. I've incorporated our latest changes (mainly API renaming & merge of all test modules into one) and edited the commits messages (typos, removed final period, added Co-authored-by tag when appropriate). You should be able to cleanly merge or rebase it on master. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-16 0:10 ` Dynamic loading progress Aurélien Aptel @ 2015-11-17 2:23 ` raman 2015-11-17 8:26 ` Steinar Bang 1 sibling, 0 replies; 765+ messages in thread From: raman @ 2015-11-17 2:23 UTC (permalink / raw) To: Aurélien Aptel; +Cc: Ted Zlatanov, Emacs development discussions Nice! Would be interesting to see if something like json parsing can be implemented via this FFI to achieve speed-up when parsing large JSON responses. -- ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-16 0:10 ` Dynamic loading progress Aurélien Aptel 2015-11-17 2:23 ` raman @ 2015-11-17 8:26 ` Steinar Bang 2015-11-17 11:08 ` Aurélien Aptel 2015-11-17 17:10 ` John Wiegley 1 sibling, 2 replies; 765+ messages in thread From: Steinar Bang @ 2015-11-17 8:26 UTC (permalink / raw) To: emacs-devel >>>>> Aurélien Aptel <aurelien.aptel+emacs@gmail.com>: > You should be able to cleanly merge or rebase it on master. Hm... wasn't dynamic loading intended as an emacs 25 feature? Is the starting point of this branch before or after the branch point of the emacs-25 branch? Note that if the starting point is a commit later than the branch point, the branch will need to be rebased to emacs-25. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-17 8:26 ` Steinar Bang @ 2015-11-17 11:08 ` Aurélien Aptel 2015-11-18 19:38 ` Ted Zlatanov 2015-11-17 17:10 ` John Wiegley 1 sibling, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-11-17 11:08 UTC (permalink / raw) To: Emacs development discussions I havent followed all the discussions on that, merge it wherever it needs to so it will be included in emacs 25 :) ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-17 11:08 ` Aurélien Aptel @ 2015-11-18 19:38 ` Ted Zlatanov 2015-11-18 20:58 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Ted Zlatanov @ 2015-11-18 19:38 UTC (permalink / raw) To: emacs-devel On Tue, 17 Nov 2015 12:08:37 +0100 Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: AA> I havent followed all the discussions on that, merge it wherever it AA> needs to so it will be included in emacs 25 :) It's merged. I made a separate post about the process, but I hope we can continue the technical discussion here: * what planned features remain unfinished? * are there any known bugs? * when do we make `--with-modules' the default? * should there be a separate manual or at least a section in the developer manual? Thanks Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-18 19:38 ` Ted Zlatanov @ 2015-11-18 20:58 ` Eli Zaretskii 2015-11-18 22:05 ` John Wiegley 2015-11-19 2:19 ` Ted Zlatanov 0 siblings, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-18 20:58 UTC (permalink / raw) To: emacs-devel > From: Ted Zlatanov <tzz@lifelogs.com> > Date: Wed, 18 Nov 2015 14:38:35 -0500 > > * what planned features remain unfinished? > * are there any known bugs? Not for me to answer, but in any case new features should go to master, I think. Therefore, I suggest to wait with them until what we have on the release branch stabilizes. (E.g., I just had to make some fixes there in the Windows-specific code, and also the code is formatted not according to our conventions.) > * when do we make `--with-modules' the default? Not in Emacs 25.1, I think. > * should there be a separate manual or at least a section in the developer manual? Of course! Every feature should be documented, and this one is no exception. I suggest to start with NEWS. Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-18 20:58 ` Eli Zaretskii @ 2015-11-18 22:05 ` John Wiegley 2015-11-19 2:19 ` Ted Zlatanov 1 sibling, 0 replies; 765+ messages in thread From: John Wiegley @ 2015-11-18 22:05 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel >>>>> Eli Zaretskii <eliz@gnu.org> writes: >> * what planned features remain unfinished? >> * are there any known bugs? > Not for me to answer, but in any case new features should go to master, I > think. Therefore, I suggest to wait with them until what we have on the > release branch stabilizes. (E.g., I just had to make some fixes there in the > Windows-specific code, and also the code is formatted not according to our > conventions.) >> * when do we make `--with-modules' the default? > Not in Emacs 25.1, I think. +1 on both points. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-18 20:58 ` Eli Zaretskii 2015-11-18 22:05 ` John Wiegley @ 2015-11-19 2:19 ` Ted Zlatanov 2015-11-19 3:39 ` Eli Zaretskii 2015-11-19 22:12 ` Philipp Stephani 1 sibling, 2 replies; 765+ messages in thread From: Ted Zlatanov @ 2015-11-19 2:19 UTC (permalink / raw) To: emacs-devel On Wed, 18 Nov 2015 22:58:16 +0200 Eli Zaretskii <eliz@gnu.org> wrote: >> From: Ted Zlatanov <tzz@lifelogs.com> >> Date: Wed, 18 Nov 2015 14:38:35 -0500 >> >> * what planned features remain unfinished? >> * are there any known bugs? EZ> Not for me to answer, but in any case new features should go to EZ> master, I think. Therefore, I suggest to wait with them until what we EZ> have on the release branch stabilizes. (E.g., I just had to make some EZ> fixes there in the Windows-specific code, and also the code is EZ> formatted not according to our conventions.) I agree that new features should go to master. I wanted to find out, for when we write the NEWS entries and other docs, and for general tracking of progress, what deficiencies (unfinished features and bugs) remain. Sorry for letting bad formatting slip through. I checked the code but I guess wasn't thorough. Would you recommend a specific tool for the formatting review? >> * should there be a separate manual or at least a section in the developer manual? EZ> Of course! Every feature should be documented, and this one is no EZ> exception. I suggest to start with NEWS. My goal with that question was actually to find out *where* the developer docs should go, not whether they are necessary. I think we all agree on the necessity. I can try a first stab at them when I know in what context they'll exist. Regarding NEWS specifically, Aurélien is absent at the moment and will be back next week. Maybe Philipp would like to provide the NEWS entries? I will write them if neither of them is able or if it can't wait until next week. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 2:19 ` Ted Zlatanov @ 2015-11-19 3:39 ` Eli Zaretskii 2015-11-19 15:26 ` Eli Zaretskii 2015-11-19 22:14 ` Philipp Stephani 2015-11-19 22:12 ` Philipp Stephani 1 sibling, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-19 3:39 UTC (permalink / raw) To: emacs-devel > From: Ted Zlatanov <tzz@lifelogs.com> > Date: Wed, 18 Nov 2015 21:19:23 -0500 > > Sorry for letting bad formatting slip through. I checked the code but I > guess wasn't thorough. Would you recommend a specific tool for the > formatting review? I just use my eyes. Maybe others can recommend some tools. > >> * should there be a separate manual or at least a section in the developer manual? > > EZ> Of course! Every feature should be documented, and this one is no > EZ> exception. I suggest to start with NEWS. > > My goal with that question was actually to find out *where* the > developer docs should go, not whether they are necessary. Sorry, it wasn't clear to me. I think the place is the ELisp manual. I see no reason to have a separate manual, since I don't expect the documentation to be large enough to justify that. Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 3:39 ` Eli Zaretskii @ 2015-11-19 15:26 ` Eli Zaretskii 2015-11-19 15:55 ` Paul Eggert 2015-11-19 22:41 ` Philipp Stephani 2015-11-19 22:14 ` Philipp Stephani 1 sibling, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-19 15:26 UTC (permalink / raw) To: Ted Zlatanov, Aurélien Aptel; +Cc: emacs-devel Thanks for making this possible. Please allow me a few questions/comments about the dynamic modules code, based on some initial reading: Why module.c, but confusingly emacs_module.h? Are there any reasons not to use the same base name, like we do for other C sources? This comment in module.c: /* If checking is enabled, abort if the current thread is not the Emacs main thread. */ static void check_main_thread (void); confused me, because a later comment says: void module_init (void) { /* It is not guaranteed that dynamic initializers run in the main thread, therefore we detect the main thread here. */ If dynamic initializers might run in a thread different from the Emacs main thread, then the code in module_init will record that other thread, not the Emacs main thread, right? Also, another comment: /* On Windows, we store both a handle to the main thread and the thread ID because the latter can be reused when a thread terminates. */ seems to imply that 'main_thread' here is not the Emacs's main thread, because that thread never terminates as long as the Emacs session is alive. So what's the deal here? what does this thread checking supposed to detect? In this code from module.c: Lisp_Object value = HASH_VALUE (h, i); eassert (NATNUMP (value)); const EMACS_UINT refcount = XFASTINT (value); if (refcount >= MOST_POSITIVE_FIXNUM) { module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); return NULL; } how can the 'if' clause ever be true? refcount is an Emacs integer, as you have just verified, no? And if this somehow can happen, then why isn't there a similar check in the other functions? Re this fragment from module.c: Lisp_Object ret = list4 (Qlambda, list2 (Qand_rest, Qargs), documentation ? build_string (documentation) : Qnil, list3 (module_call_func, envobj, Qargs)); Thou shalt not use build_string, except when you _know_ the argument will always be a pure-ASCII string. Practically, this means the argument must be a constant ASCII string. See these messages (and the preceding discussion, if you are interested) for the gory details: http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00955.html http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00976.html http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00979.html The above should call make_multibyte_string instead. Again in module.c: /* * Emacs internal encoding is more-or-less UTF8, let's assume utf8 * encoded emacs string are the same byte size. */ if (!buffer || length == 0 || *length-1 < raw_size) { *length = raw_size + 1; return false; } I don't understand why you need this assumption. You are going to encode the string in a moment, so why not test 'length' against the size you actually obtain there? (The above test will misfire when the original string includes characters above the Unicode codespace, which require 5 bytes internally, but their encoding maps them to Unicode codepoints which cannot take more than 4 bytes. So you might reject perfectly valid calls.) In module_make_string you have: /* Assume STR is utf8 encoded */ return lisp_to_value (env, make_string (str, length)); The discussion I pointed to above concluded that <quote>make_string is a bug</quote>. So please use make_multibyte_string here instead. It looks like XUSER_PTR is used both as an lvalue and an rvalue. This is different from any other object, where we have separate Xfoo and XSETfoo macros. Suggest to follow suit. static void module_set_user_finalizer (emacs_env *env, emacs_value uptr, emacs_finalizer_function fin) { check_main_thread (); eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return); const Lisp_Object lisp = value_to_lisp (uptr); if (! USER_PTRP (lisp)) module_wrong_type (env, Quser_ptr, lisp); XUSER_PTR (lisp)->finalizer = fin; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< } No validity checks on 'fin'? In module_vec_get: /* Prevent error-prone comparison between types of different signedness. */ const size_t size = ASIZE (lvec); eassert (size >= 0); How can the assertion be ever violated? In module-load: CHECK_STRING (file); handle = dynlib_open (SDATA (file)); Every Lisp primitive that accepts file arguments _must_ call expand-file-name on the file name, before using it. Otherwise, relative file names will produce subtle and hard-to-debug problems when the Lisp program calling them involves changing the current directory of the Emacs process. The other mandatory thing absent from the above is ENCODE_FILE. You cannot pass unencoded file names to C runtime functions. struct { struct emacs_runtime pub; struct emacs_runtime_private priv; } runtime = { .pub = { .size = sizeof runtime.pub, .get_environment = module_get_environment, .private_members = &runtime.priv } }; Is this portable enough? int r = module_init (&runtime.pub); I think calling this function "module_init" is sub-optimal: you have a void function by the same name in this source file. How about renaming it to something else? Also, it seems that once a module is loaded, it cannot be unloaded (i.e., no unload-feature equivalent is provided). Is that on purpose? An Emacs process can live for a very long time, so keeping all of the modules open in it at all times is not necessarily TRT. E.g., how do I update to a newer version of a module? Shouldn't module-init call dynlib_close before it returns? Otherwise we are leaking descriptors here, no? In module-call: const EMACS_INT len = XINT (Flength (arglist)); eassert (len >= 0); if (len > MOST_POSITIVE_FIXNUM) xsignal0 (Qoverflow_error); How can the 'if' clause ever be true? XINT by definition cannot produce anything but a valid EMACS_INT, can it? if (len > INT_MAX || len < envptr->min_arity || (envptr->max_arity >= 0 && len > envptr->max_arity)) xsignal2 (Qwrong_number_of_arguments, module_format_fun_env (envptr), make_number (len)); Why the test against INT_MAX? EMACS_INT can legitimately be a 64-bit data type with values far exceeding INT_MAX. Why impose this limitation here? allocate_emacs_value calls malloc; shouldn't it call xmalloc instead, or at least conform to the XMALLOC_BLOCK_INPUT_CHECK protocol? In module_format_fun_env, you produce a unibyte string, and then use that in calls to functions like xsignal1, which expect Lisp strings in their internal multibyte representation. You should instead decode the unibyte string (using UTF-8) before you return it. Btw, I wonder whether we should provide a more friendly capabilities for retrieving the function name and its module. dladdr is not portable enough, and we have all the information at our fingertips in the module's init function, we just need to keep it instead of throwing it away. I envision debugging module-related problems will not be a very rare situation, so we need any help we can get. WDYT? In syms_of_module: /* Unintern `module-environments' because it is only used internally. */ Funintern (Qmodule_environments, Qnil); What if some Lisp defines a (interned) symbol by that name? Won't they clash? The Windows-specific parts of dynlib.c need work, e.g. you cannot pass UTF-8 encoded file names to Windows APIs. And there are some other issues. I'll take care of that. About the tests: The Makefile in mod-test is Unix-specific: it uses a literal .so extension. I also think the Python script should be rewritten in Emacs Lisp, so that Python installation is not required. Finally, all of the module tests and associated files should be moved into test/, preferably even test/automated/ and made part of the "make check" run. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 15:26 ` Eli Zaretskii @ 2015-11-19 15:55 ` Paul Eggert 2015-11-19 16:27 ` Eli Zaretskii ` (3 more replies) 2015-11-19 22:41 ` Philipp Stephani 1 sibling, 4 replies; 765+ messages in thread From: Paul Eggert @ 2015-11-19 15:55 UTC (permalink / raw) To: Eli Zaretskii, Ted Zlatanov, Aurélien Aptel; +Cc: emacs-devel Eli, thanks very much for doing that review. It's clear we have a lot of work to do in the new module code. I have also been reviewing it and have some changes sort-of-prepared, and I'll try to start folding them in soon. The main thing I noticed (that was not already in your list or in my upcoming changes) are some problems in memory allocation. The module code calls malloc directly, instead of xmalloc, for reasons I don't understand. This leads to problems, e.g., the memory is not properly accounted for by the memory profiler. Why can't the new module code invoke xmalloc? More generally, how should modules obtain memory in an Emacs-friendly way? Also, the file name "emacs_module.h" doesn't use the usual Emacs style rules; hyphen not underscore. But as you say, "module.h" would be better anyway. I'll change it to "module.h" for now; if there's some reason it needs an "emacs" prefix we can change it to "emacs-module.h" later. There are some other things I noticed which I'll try to summarize after fixing the stuff that's easy to fix (missing copyright notices, formatting, etc.). ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 15:55 ` Paul Eggert @ 2015-11-19 16:27 ` Eli Zaretskii 2015-11-19 16:37 ` Paul Eggert 2015-11-19 17:26 ` Eli Zaretskii ` (2 subsequent siblings) 3 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-19 16:27 UTC (permalink / raw) To: Paul Eggert; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > Cc: emacs-devel@gnu.org > From: Paul Eggert <eggert@cs.ucla.edu> > Date: Thu, 19 Nov 2015 07:55:34 -0800 > > The main thing I noticed (that was not already in your list or in my > upcoming changes) are some problems in memory allocation. The module > code calls malloc directly, instead of xmalloc, for reasons I don't > understand. I suspect the reason is the same that it doesn't call CHECK_NUMBER etc., but instead emulates that in its own code: the authors wanted to refrain from causing a non-local exit directly, they wanted such exits to go through their own non-local exit routine. But that's a guess. If this is indeed the reason, we should probably look for a better solution. > More generally, how should modules obtain memory in an > Emacs-friendly way? The code in module.c runs in Emacs, so I think it's friendly enough (apart of the xmalloc issue). Or did I misunderstand what you meant? > There are some other things I noticed which I'll try to summarize after > fixing the stuff that's easy to fix (missing copyright notices, > formatting, etc.). Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 16:27 ` Eli Zaretskii @ 2015-11-19 16:37 ` Paul Eggert 2015-11-19 17:04 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-19 16:37 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel On 11/19/2015 08:27 AM, Eli Zaretskii wrote: > The code in module.c runs in Emacs, so I think it's friendly enough > (apart of the xmalloc issue). Or did I misunderstand what you meant? It's the xmalloc issue. That is, if a module contains random C code inside a library outside of your control that invokes malloc, I suppose it's a lost cause, we can't memory-profile that. But if as part of a module you write a wrapper for Emacs, the wrapper code should use xmalloc rather than malloc, so that at least we can account for its memory and fail in a standard way if it's not available. That sort of thing. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 16:37 ` Paul Eggert @ 2015-11-19 17:04 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-19 17:04 UTC (permalink / raw) To: Paul Eggert; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, emacs-devel@gnu.org > From: Paul Eggert <eggert@cs.ucla.edu> > Date: Thu, 19 Nov 2015 08:37:53 -0800 > > On 11/19/2015 08:27 AM, Eli Zaretskii wrote: > > The code in module.c runs in Emacs, so I think it's friendly enough > > (apart of the xmalloc issue). Or did I misunderstand what you meant? > > It's the xmalloc issue. That is, if a module contains random C code > inside a library outside of your control that invokes malloc, I suppose > it's a lost cause, we can't memory-profile that. But if as part of a > module you write a wrapper for Emacs, the wrapper code should use > xmalloc rather than malloc, so that at least we can account for its > memory and fail in a standard way if it's not available. That sort of thing. Right. I think we should be able to provide an xmalloc-compatible function for module.c to use, once we know exactly why xmalloc was avoided. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 15:55 ` Paul Eggert 2015-11-19 16:27 ` Eli Zaretskii @ 2015-11-19 17:26 ` Eli Zaretskii 2015-11-19 17:32 ` Paul Eggert 2015-11-19 17:57 ` Stephen Leake 2015-11-19 22:45 ` Philipp Stephani 3 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-19 17:26 UTC (permalink / raw) To: Paul Eggert; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > From: Paul Eggert <eggert@cs.ucla.edu> > Date: Thu, 19 Nov 2015 07:55:34 -0800 > Cc: emacs-devel@gnu.org > > Eli, thanks very much for doing that review. It's clear we have a lot of > work to do in the new module code. I have also been reviewing it and > have some changes sort-of-prepared, and I'll try to start folding them > in soon. Do any of those changes touch modules/mod-test/Makefile (apart of those in the copyright notice you've already pushed)? I have a few changes there, to allow running the tests on MS-Windows, at least manually, but if you are working on that file, I will wait until you push. Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 17:26 ` Eli Zaretskii @ 2015-11-19 17:32 ` Paul Eggert 2015-11-19 17:50 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-19 17:32 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel On 11/19/2015 09:26 AM, Eli Zaretskii wrote: > Do any of those changes touch modules/mod-test/Makefile Not yet :-). Please go ahead and install the changes you have in mind, I'll merge anything else that comes up. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 17:32 ` Paul Eggert @ 2015-11-19 17:50 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-19 17:50 UTC (permalink / raw) To: Paul Eggert; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, emacs-devel@gnu.org > From: Paul Eggert <eggert@cs.ucla.edu> > Date: Thu, 19 Nov 2015 09:32:39 -0800 > > Please go ahead and install the changes you have in mind, Done, thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 15:55 ` Paul Eggert 2015-11-19 16:27 ` Eli Zaretskii 2015-11-19 17:26 ` Eli Zaretskii @ 2015-11-19 17:57 ` Stephen Leake 2015-11-19 18:06 ` Eli Zaretskii 2015-11-19 22:45 ` Philipp Stephani 3 siblings, 1 reply; 765+ messages in thread From: Stephen Leake @ 2015-11-19 17:57 UTC (permalink / raw) To: Paul Eggert; +Cc: Aurélien Aptel, Eli Zaretskii, Ted Zlatanov, emacs-devel Paul Eggert <eggert@cs.ucla.edu> writes: > Also, the file name "emacs_module.h" doesn't use the usual Emacs style > rules; hyphen not underscore. But as you say, "module.h" would be > better anyway. I'll change it to "module.h" for now; if there's some > reason it needs an "emacs" prefix we can change it to "emacs-module.h" > later. "emacs_module.h" is the only Emacs file that client code (that defines modules) includes. Therefore, it should have "emacs" in the name for namespace management; client code might have "module.h" for some other purpose. Changing to "emacs-module.h" makes sense. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 17:57 ` Stephen Leake @ 2015-11-19 18:06 ` Eli Zaretskii 2015-11-19 18:53 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-19 18:06 UTC (permalink / raw) To: Stephen Leake; +Cc: aurelien.aptel+emacs, tzz, eggert, emacs-devel > From: Stephen Leake <stephen_leake@stephe-leake.org> > Cc: Eli Zaretskii <eliz@gnu.org>, Ted Zlatanov <tzz@lifelogs.com>, > Aurélien Aptel <aurelien.aptel+emacs@gmail.com>, > emacs-devel@gnu.org > Date: Thu, 19 Nov 2015 11:57:48 -0600 > > "emacs_module.h" is the only Emacs file that client code (that defines > modules) includes. Therefore, it should have "emacs" in the name for > namespace management; client code might have "module.h" for some other > purpose. > > Changing to "emacs-module.h" makes sense. But then module.c should be renamed to emacs-module.c. Or even emodule.[ch], which is shorter. Alternatively, we could have an internal and an external header files; the latter will have to be installed by "make install" in the include tree, and so doesn't have to be used for internal compilation. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 18:06 ` Eli Zaretskii @ 2015-11-19 18:53 ` Paul Eggert 2015-11-19 20:27 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-19 18:53 UTC (permalink / raw) To: Eli Zaretskii, Stephen Leake; +Cc: aurelien.aptel+emacs, tzz, emacs-devel On 11/19/2015 10:06 AM, Eli Zaretskii wrote: > But then module.c should be renamed to emacs-module.c. Or even > emodule.[ch], which is shorter. A quick Google search suggests that Enlightenment uses emodule.h, so if we want the name to be globally unique then we'll need a more-specific name like emacs-module.h or gemodule.h (and likewise for .c). > Alternatively, we could have an internal and an external header files; > the latter will have to be installed by "make install" in the include > tree, and so doesn't have to be used for internal compilation. If possible I'd rather use the same .h file for both internal and external. Simpler, more-often checked, that sort of thing. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 18:53 ` Paul Eggert @ 2015-11-19 20:27 ` Eli Zaretskii 2015-11-19 20:31 ` John Wiegley 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-19 20:27 UTC (permalink / raw) To: Paul Eggert; +Cc: aurelien.aptel+emacs, tzz, stephen_leake, emacs-devel > From: Paul Eggert <eggert@cs.ucla.edu> > Date: Thu, 19 Nov 2015 10:53:44 -0800 > Cc: aurelien.aptel+emacs@gmail.com, tzz@lifelogs.com, emacs-devel@gnu.org > > On 11/19/2015 10:06 AM, Eli Zaretskii wrote: > > But then module.c should be renamed to emacs-module.c. Or even > > emodule.[ch], which is shorter. > > A quick Google search suggests that Enlightenment uses emodule.h, so if > we want the name to be globally unique then we'll need a more-specific > name like emacs-module.h or gemodule.h (and likewise for .c). > > > Alternatively, we could have an internal and an external header files; > > the latter will have to be installed by "make install" in the include > > tree, and so doesn't have to be used for internal compilation. > > If possible I'd rather use the same .h file for both internal and > external. Simpler, more-often checked, that sort of thing. I'm okay with emacs-module.[ch]. Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 20:27 ` Eli Zaretskii @ 2015-11-19 20:31 ` John Wiegley 0 siblings, 0 replies; 765+ messages in thread From: John Wiegley @ 2015-11-19 20:31 UTC (permalink / raw) To: Eli Zaretskii Cc: aurelien.aptel+emacs, tzz, Paul Eggert, stephen_leake, emacs-devel >>>>> Eli Zaretskii <eliz@gnu.org> writes: > I'm okay with emacs-module.[ch]. Me too. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 15:55 ` Paul Eggert ` (2 preceding siblings ...) 2015-11-19 17:57 ` Stephen Leake @ 2015-11-19 22:45 ` Philipp Stephani 2015-11-19 22:55 ` Paul Eggert 3 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-19 22:45 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1807 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am Do., 19. Nov. 2015 um 16:55 Uhr: > The main thing I noticed (that was not already in your list or in my > upcoming changes) are some problems in memory allocation. The module > code calls malloc directly, instead of xmalloc, for reasons I don't > understand. This leads to problems, e.g., the memory is not properly > accounted for by the memory profiler. Why can't the new module code > invoke xmalloc? More generally, how should modules obtain memory in an > Emacs-friendly way? > The problem with xmalloc is that it can signal (i.e. call longjmp). Modules are generally not prepared for long jumps, so it's important that no longjmp escapes into module code. The easiest way to ensure this is to make code not call longjmp in the first place. Some of the code in module.c does call longjmp; that is protected by appropriate calls to setjmp. We could do that with all code, but for cases like malloc it seemed simple enough to avoid the calls to longjmp altogether. Maybe we should add a variant that behaves like xmalloc but is guaranteed to never call longjmp? > > Also, the file name "emacs_module.h" doesn't use the usual Emacs style > rules; hyphen not underscore. If a hyphen is preferred, feel free to rename. > But as you say, "module.h" would be better > anyway. I'll change it to "module.h" for now; if there's some reason it > needs an "emacs" prefix we can change it to "emacs-module.h" later. > > Please don't use module.h; this header file is the only one that is intended for module authors to include, so it needs a globally unique name which should start with 'emacs'. > There are some other things I noticed which I'll try to summarize after > fixing the stuff that's easy to fix (missing copyright notices, > formatting, etc.). > > [-- Attachment #2: Type: text/html, Size: 2664 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 22:45 ` Philipp Stephani @ 2015-11-19 22:55 ` Paul Eggert 2015-11-19 23:08 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-19 22:55 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel Cc: emacs-devel On 11/19/2015 02:45 PM, Philipp Stephani wrote: > Maybe we should add a variant that behaves like xmalloc but is > guaranteed to never call longjmp? What should this new xmalloc variant do when it runs out of memory? xmalloc never returns NULL, so presumably that should be true for the variant as well. > > Please don't use module.h; this header file is the only one that is > intended for module authors to include, so it needs a globally unique > name which should start with 'emacs'. Yes, that's already done, it's renamed to emacs-module.h now. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 22:55 ` Paul Eggert @ 2015-11-19 23:08 ` Philipp Stephani 2015-11-19 23:50 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-19 23:08 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 756 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am Do., 19. Nov. 2015 um 23:56 Uhr: > On 11/19/2015 02:45 PM, Philipp Stephani wrote: > > Maybe we should add a variant that behaves like xmalloc but is > > guaranteed to never call longjmp? > > What should this new xmalloc variant do when it runs out of memory? > xmalloc never returns NULL, so presumably that should be true for the > variant as well. > Returning NULL is fine. malloc also returns NULL on OOM, and module.c handles that. > > > > > Please don't use module.h; this header file is the only one that is > > intended for module authors to include, so it needs a globally unique > > name which should start with 'emacs'. > > Yes, that's already done, it's renamed to emacs-module.h now. > Thanks. [-- Attachment #2: Type: text/html, Size: 1256 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 23:08 ` Philipp Stephani @ 2015-11-19 23:50 ` Paul Eggert 2015-11-19 23:55 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-19 23:50 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel Cc: emacs-devel On 11/19/2015 03:08 PM, Philipp Stephani wrote: > Returning NULL is fine. malloc also returns NULL on OOM, and module.c > handles that. I'm not so much worried about emacs-module.c. I'm worried about what modules will do. If we tell programmers 'just call xmalloc' things will be easy for them. If not, they'll be more likely to make mistakes. Is there some way xmalloc (actually, memory_full) can detect that it was invoked from a module rather than from ordinary Emacs code? If so, we could have memory_full do something different than call xsignal, in that case. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 23:50 ` Paul Eggert @ 2015-11-19 23:55 ` Philipp Stephani 2015-11-19 23:58 ` Paul Eggert 2015-11-20 10:11 ` Eli Zaretskii 0 siblings, 2 replies; 765+ messages in thread From: Philipp Stephani @ 2015-11-19 23:55 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 869 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am Fr., 20. Nov. 2015 um 00:50 Uhr: > On 11/19/2015 03:08 PM, Philipp Stephani wrote: > > Returning NULL is fine. malloc also returns NULL on OOM, and module.c > > handles that. > > I'm not so much worried about emacs-module.c. I'm worried about what > modules will do. If we tell programmers 'just call xmalloc' things will > be easy for them. If not, they'll be more likely to make mistakes. > > Is there some way xmalloc (actually, memory_full) can detect that it was > invoked from a module rather than from ordinary Emacs code? If so, we > could have memory_full do something different than call xsignal, in that > case. > Modules cannot (legally) call xmalloc. They need to obtain memory using malloc or any other standard function. In general, modules cannot call any functions except those declared in emacs-module.h. [-- Attachment #2: Type: text/html, Size: 1200 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 23:55 ` Philipp Stephani @ 2015-11-19 23:58 ` Paul Eggert 2015-11-20 19:23 ` Philipp Stephani 2015-11-20 10:11 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-19 23:58 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel Cc: emacs-devel On 11/19/2015 03:55 PM, Philipp Stephani wrote: > Modules cannot (legally) call xmalloc. They need to obtain memory > using malloc or any other standard function. In general, modules > cannot call any functions except those declared in emacs-module.h. I'm suggesting that we declare a memory allocator in emacs-module.h. Sorry if that wasn't clear. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 23:58 ` Paul Eggert @ 2015-11-20 19:23 ` Philipp Stephani 2015-11-20 21:04 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-20 19:23 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 726 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am Fr., 20. Nov. 2015 um 00:58 Uhr: > On 11/19/2015 03:55 PM, Philipp Stephani wrote: > > Modules cannot (legally) call xmalloc. They need to obtain memory > > using malloc or any other standard function. In general, modules > > cannot call any functions except those declared in emacs-module.h. > > I'm suggesting that we declare a memory allocator in emacs-module.h. > Sorry if that wasn't clear. > We can do that, but I don't expect modules to use it. Modules will typically be used to wrap existing C or C++ libraries or make heavy use of such libraries, and those libraries won't use an Emacs-specific allocator. What could go wrong if modules use malloc for memory allocation? [-- Attachment #2: Type: text/html, Size: 1050 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 19:23 ` Philipp Stephani @ 2015-11-20 21:04 ` Paul Eggert 2015-11-20 22:44 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-20 21:04 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel Cc: emacs-devel Philipp Stephani wrote: > Modules will > typically be used to wrap existing C or C++ libraries or make heavy use of > such libraries, and those libraries won't use an Emacs-specific allocator. It's quite likely that wrappers will need to allocate memory to marshal data back and forth between C and Elisp. If I wanted to build a module to use GMP, for example, I'd want to use GMP's low-level primitives that don't do memory management, and have the wrapper manage memory itself. I suppose some wrappers won't need to manage memory at all, but I'd say most libraries need memory, and the overall system will benefit from having a single memory manager rather than having each library manage its own memory independently. Have you used the Emacs memory profiler? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 21:04 ` Paul Eggert @ 2015-11-20 22:44 ` Philipp Stephani 0 siblings, 0 replies; 765+ messages in thread From: Philipp Stephani @ 2015-11-20 22:44 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1189 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am Fr., 20. Nov. 2015 um 22:04 Uhr: > Philipp Stephani wrote: > > Modules will > > typically be used to wrap existing C or C++ libraries or make heavy use > of > > such libraries, and those libraries won't use an Emacs-specific > allocator. > > It's quite likely that wrappers will need to allocate memory to marshal > data > back and forth between C and Elisp. If I wanted to build a module to use > GMP, > for example, I'd want to use GMP's low-level primitives that don't do > memory > management, and have the wrapper manage memory itself. > > I suppose some wrappers won't need to manage memory at all, but I'd say > most > libraries need memory, and the overall system will benefit from having a > single > memory manager rather than having each library manage its own memory > independently. > That sounds reasonable, and since there is no other way for modules to use Emacs's allocator it would make sense to add it to the module interface (the env object), as long as modules remain free to pick any allocator. > > Have you used the Emacs memory profiler? > I think once, but not regularly. Still sounds like a useful thing to have. [-- Attachment #2: Type: text/html, Size: 1691 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 23:55 ` Philipp Stephani 2015-11-19 23:58 ` Paul Eggert @ 2015-11-20 10:11 ` Eli Zaretskii 2015-11-20 20:00 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-20 10:11 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, eggert, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Thu, 19 Nov 2015 23:55:57 +0000 > Cc: emacs-devel@gnu.org > > Modules cannot (legally) call xmalloc. They need to obtain memory using malloc > or any other standard function. How is calling malloc different from calling xmalloc? Neither is in the interface defined in emacs-module.h, right? > In general, modules cannot call any functions except those declared > in emacs-module.h. Can they call functions from external libraries? (I thought allowing that was one of the main design goals.) If so, what's the difference? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 10:11 ` Eli Zaretskii @ 2015-11-20 20:00 ` Philipp Stephani 0 siblings, 0 replies; 765+ messages in thread From: Philipp Stephani @ 2015-11-20 20:00 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, eggert, emacs-devel [-- Attachment #1: Type: text/plain, Size: 941 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am Fr., 20. Nov. 2015 um 11:11 Uhr: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Thu, 19 Nov 2015 23:55:57 +0000 > > Cc: emacs-devel@gnu.org > > > > Modules cannot (legally) call xmalloc. They need to obtain memory using > malloc > > or any other standard function. > > How is calling malloc different from calling xmalloc? Neither is in > the interface defined in emacs-module.h, right? > malloc is a standard C function, xmalloc is an internal Emacs function. > > > In general, modules cannot call any functions except those declared > > in emacs-module.h. > > Can they call functions from external libraries? (I thought allowing > that was one of the main design goals.) If so, what's the difference? > yes, sorry, I was being sloppy. Modules cannot call any Emacs C functions except those declared in emacs-module.h. Of course they can call arbitrary other library functions. [-- Attachment #2: Type: text/html, Size: 1562 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 15:26 ` Eli Zaretskii 2015-11-19 15:55 ` Paul Eggert @ 2015-11-19 22:41 ` Philipp Stephani 2015-11-19 23:51 ` Paul Eggert 2015-11-20 9:53 ` Eli Zaretskii 1 sibling, 2 replies; 765+ messages in thread From: Philipp Stephani @ 2015-11-19 22:41 UTC (permalink / raw) To: Eli Zaretskii, Ted Zlatanov, Aurélien Aptel; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 12401 bytes --] Thanks for the thorough review; I'll prepare patches for all of these issues. Eli Zaretskii <eliz@gnu.org> schrieb am Do., 19. Nov. 2015 um 16:28 Uhr: > Thanks for making this possible. > > Please allow me a few questions/comments about the dynamic modules > code, based on some initial reading: > > Why module.c, but confusingly emacs_module.h? Are there any reasons > not to use the same base name, like we do for other C sources? > > emacs_module.h is intended to be included by module authors. Therefore its name needs to be globally unique, which in practice means it needs to start with 'emacs_'. module.c could be renamed accordingly, if you prefer that. However, Aurélien picked the simple name because it's not required to be globally unique. > This comment in module.c: > > /* If checking is enabled, abort if the current thread is not the > Emacs main thread. */ > static void check_main_thread (void); > > confused me, because a later comment says: > > void module_init (void) > { > /* It is not guaranteed that dynamic initializers run in the main > thread, > therefore we detect the main thread here. */ > > If dynamic initializers might run in a thread different from the Emacs > main thread, then the code in module_init will record that other > thread, not the Emacs main thread, right? > No, because module_init is guaranteed to be called from the main thread because main calls it explicitly. > > Also, another comment: > > /* On Windows, we store both a handle to the main thread and the > thread ID because the latter can be reused when a thread > terminates. */ > > seems to imply that 'main_thread' here is not the Emacs's main thread, > because that thread never terminates as long as the Emacs session is > alive. > > So what's the deal here? what does this thread checking supposed to > detect? > This guards against the Emacs main thread having exited while module code in some other thread is still running and attempting to call Emacs functions. This is undefined behavior, but we included an explicit check if checking is enabled because that case is somewhat subtle. > > In this code from module.c: > > Lisp_Object value = HASH_VALUE (h, i); > eassert (NATNUMP (value)); > const EMACS_UINT refcount = XFASTINT (value); > if (refcount >= MOST_POSITIVE_FIXNUM) > { > module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); > return NULL; > } > > how can the 'if' clause ever be true? refcount is an Emacs integer, > as you have just verified, no? And if this somehow can happen, then > why isn't there a similar check in the other functions? > refcount can be MOST_POSITIVE_FIXNUM because that's an inclusive bound. It's important to check that case because later refcount is incremented by one, and if it's equal to MOST_POSITIVE_FIXNUM it would be outside the allowed range afterwards. No other function increments numbers, thus no other functions need this check. > > Re this fragment from module.c: > > Lisp_Object ret = list4 (Qlambda, > list2 (Qand_rest, Qargs), > documentation ? build_string (documentation) : > Qnil, > list3 (module_call_func, > envobj, > Qargs)); > > Thou shalt not use build_string, except when you _know_ the argument > will always be a pure-ASCII string. Practically, this means the > argument must be a constant ASCII string. See these messages (and the > preceding discussion, if you are interested) for the gory details: > > http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00955.html > http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00976.html > http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00979.html > > The above should call make_multibyte_string instead. > We had a discussion about encodings in https://github.com/aaptel/emacs-dynamic-module/issues/37. Sorry that this didn't get resolved earlier; it's an important point. My suggestion would be to always mandate specifying an encoding whenever a char* is passed, and limit that to two or three functions dealing with creating strings and accessing string contents. Would that address your concerns? > > Again in module.c: > > /* > * Emacs internal encoding is more-or-less UTF8, let's assume utf8 > * encoded emacs string are the same byte size. > */ > > if (!buffer || length == 0 || *length-1 < raw_size) > { > *length = raw_size + 1; > return false; > } > > I don't understand why you need this assumption. You are going to > encode the string in a moment, so why not test 'length' against the > size you actually obtain there? (The above test will misfire when the > original string includes characters above the Unicode codespace, which > require 5 bytes internally, but their encoding maps them to Unicode > codepoints which cannot take more than 4 bytes. So you might reject > perfectly valid calls.) > > In module_make_string you have: > > /* Assume STR is utf8 encoded */ > return lisp_to_value (env, make_string (str, length)); > > The discussion I pointed to above concluded that <quote>make_string is > a bug</quote>. So please use make_multibyte_string here instead. > See above; my suggestion would be to change the string handling code by limiting encoding and decoding to a small set of functions where the encoding would have to be specified explicitly. > > It looks like XUSER_PTR is used both as an lvalue and an rvalue. This > is different from any other object, where we have separate Xfoo and > XSETfoo macros. Suggest to follow suit. > Agreed. > > static void module_set_user_finalizer (emacs_env *env, > emacs_value uptr, > emacs_finalizer_function fin) > { > check_main_thread (); > eassert (module_non_local_exit_check (env) == > emacs_funcall_exit_return); > const Lisp_Object lisp = value_to_lisp (uptr); > if (! USER_PTRP (lisp)) module_wrong_type (env, Quser_ptr, lisp); > XUSER_PTR (lisp)->finalizer = fin; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< > } > > No validity checks on 'fin'? > How should it be validated? In C an arbitrary (invalid) pointer could be passed. I think we just have to accept that this is UB. > > In module_vec_get: > > /* Prevent error-prone comparison between types of different signedness. > */ > const size_t size = ASIZE (lvec); > eassert (size >= 0); > > How can the assertion be ever violated? > Yeah, that's a bug. I probably meant size to be declared as ptrdiff_t, which is what ASIZE returns. > > In module-load: > > CHECK_STRING (file); > handle = dynlib_open (SDATA (file)); > > Every Lisp primitive that accepts file arguments _must_ call > expand-file-name on the file name, before using it. Otherwise, > relative file names will produce subtle and hard-to-debug problems > when the Lisp program calling them involves changing the current > directory of the Emacs process. > > The other mandatory thing absent from the above is ENCODE_FILE. You > cannot pass unencoded file names to C runtime functions. > OK, will send a patch. > > struct { > struct emacs_runtime pub; > struct emacs_runtime_private priv; > } runtime = { > .pub = { > .size = sizeof runtime.pub, > .get_environment = module_get_environment, > .private_members = &runtime.priv > } > }; > > Is this portable enough? > According to http://en.cppreference.com/w/c/language/struct_initialization and https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html designated initializers are part of C99, which is required for building Emacs. > > int r = module_init (&runtime.pub); > > I think calling this function "module_init" is sub-optimal: you have a > void function by the same name in this source file. How about > renaming it to something else? > Agree > > Also, it seems that once a module is loaded, it cannot be unloaded > (i.e., no unload-feature equivalent is provided). Is that on purpose? > An Emacs process can live for a very long time, so keeping all of the > modules open in it at all times is not necessarily TRT. E.g., how do > I update to a newer version of a module? > Unloading is important ( https://github.com/aaptel/emacs-dynamic-module/issues/36), but for now we decided to delay it to a later version because we expect much discussion about the precise semantics. > > Shouldn't module-init call dynlib_close before it returns? Otherwise > we are leaking descriptors here, no? > My impression from reading dlclose(3) is that modules shouldn't be unloaded while they are still used. > > In module-call: > > const EMACS_INT len = XINT (Flength (arglist)); > eassert (len >= 0); > if (len > MOST_POSITIVE_FIXNUM) > xsignal0 (Qoverflow_error); > > How can the 'if' clause ever be true? XINT by definition cannot > produce anything but a valid EMACS_INT, can it? > True. Not sure what I was thinking. (Could be replaced by an eassert, to document the assumption.) > > if (len > INT_MAX || len < envptr->min_arity || (envptr->max_arity >= 0 > && len > envptr->max_arity)) > xsignal2 (Qwrong_number_of_arguments, module_format_fun_env (envptr), > make_number (len)); > > Why the test against INT_MAX? EMACS_INT can legitimately be a 64-bit > data type with values far exceeding INT_MAX. Why impose this > limitation here? > Because the nargs argument in the module interface is an int. If you think functions with more than INT_MAX arguments should be supported, the type for nargs should be changed to int64. > > allocate_emacs_value calls malloc; shouldn't it call xmalloc instead, > or at least conform to the XMALLOC_BLOCK_INPUT_CHECK protocol? > If xmalloc is called, then we need to make sure that no signals (longjmps) can escape to module code. If appropriate setjmps are in place that should be doable, but I need to check whether there are edge cases. > > In module_format_fun_env, you produce a unibyte string, and then use > that in calls to functions like xsignal1, which expect Lisp strings in > their internal multibyte representation. You should instead decode > the unibyte string (using UTF-8) before you return it. > OK, will send a patch. > > Btw, I wonder whether we should provide a more friendly capabilities > for retrieving the function name and its module. dladdr is not > portable enough, and we have all the information at our fingertips > in the module's init function, we just need to keep it instead of > throwing it away. I envision debugging module-related problems will > not be a very rare situation, so we need any help we can get. WDYT? > Hmm, I don't know whether we have access to the function name without using dladdr. The user just passes a pointer to the module, not its name. > > In syms_of_module: > > /* Unintern `module-environments' because it is only used > internally. */ > Funintern (Qmodule_environments, Qnil); > > What if some Lisp defines a (interned) symbol by that name? Won't > they clash? > I followed the lead of internal-interpreter-environment in eval.c, which uses the same pattern. > > The Windows-specific parts of dynlib.c need work, e.g. you cannot pass > UTF-8 encoded file names to Windows APIs. And there are some other > issues. I'll take care of that. > I can also do that, I should be able to set up a build environment in a VM. > > About the tests: The Makefile in mod-test is Unix-specific: it uses a > literal .so extension. I also think the Python script should be > rewritten in Emacs Lisp, so that Python installation is not required. > Finally, all of the module tests and associated files should be moved > into test/, preferably even test/automated/ and made part of the "make > check" run. > > Yes, tracked in https://github.com/aaptel/emacs-dynamic-module/issues/34 [-- Attachment #2: Type: text/html, Size: 17434 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 22:41 ` Philipp Stephani @ 2015-11-19 23:51 ` Paul Eggert 2015-11-19 23:57 ` Philipp Stephani 2015-11-20 9:53 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-19 23:51 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel Cc: emacs-devel On 11/19/2015 02:41 PM, Philipp Stephani wrote: > > Yeah, that's a bug. I probably meant size to be declared as ptrdiff_t, > which is what ASIZE returns. I've fixed this by changing size_t to ptrdiff_t in the new code (or to int, if it's guaranteed to fit in INT_MAX). > According to > http://en.cppreference.com/w/c/language/struct_initialization and > https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html designated > initializers are part of C99, which is required for building Emacs. I think designated initializers are pretty safe nowadays. (We don't assume all of C99 even now, by the way, just a reasonably portable subset; but this should be in the subset). That particular initializer is overkill, though. It's not obvious to the casual reader that it initializes the private members to zero, and I doubt whether any such initialization was intended. (This is one of the downsides of C99 initializers.) I simplified it. I have more work to do in this area and plan to follow up later. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 23:51 ` Paul Eggert @ 2015-11-19 23:57 ` Philipp Stephani 2015-11-20 0:03 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-19 23:57 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 590 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am Fr., 20. Nov. 2015 um 00:51 Uhr: > On 11/19/2015 02:41 PM, Philipp Stephani wrote: > > > > Yeah, that's a bug. I probably meant size to be declared as ptrdiff_t, > > which is what ASIZE returns. > > I've fixed this by changing size_t to ptrdiff_t in the new code (or to > int, if it's guaranteed to fit in INT_MAX). > > Thanks. I saw you changed some other members to ptrdiff_t (the public size members of emacs_runtime and emacs_env), is that intentional, and if so, what is the reason? Anyway, emacs-module.h now lacks an #include <stddef.h>. [-- Attachment #2: Type: text/html, Size: 911 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 23:57 ` Philipp Stephani @ 2015-11-20 0:03 ` Paul Eggert 2015-11-20 19:29 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-20 0:03 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel Cc: emacs-devel On 11/19/2015 03:57 PM, Philipp Stephani wrote: > Thanks. I saw you changed some other members to ptrdiff_t (the public > size members of emacs_runtime and emacs_env), is that intentional, and > if so, what is the reason? As a general rule, in Emacs source code we prefer signed arithmetic to unsigned, because the latter is so error prone when it comes to comparisons. Also, signed arithmetic allows for better low-level checking, e.g., with -fsanitize=undefined. (There are a few exceptions, e.g., hash values, but they're relatively rare.) So the module interface should encourage the use of signed integer arithmetic when possible. It might also be useful to support modules that, for whatever reason, cannot deal with signed integers and must use unsigned integers. That could be something we add later, if necessary. > Anyway, emacs-module.h now lacks an #include <stddef.h>. Thanks, fixed now. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 0:03 ` Paul Eggert @ 2015-11-20 19:29 ` Philipp Stephani 2015-11-20 20:47 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-20 19:29 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1812 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am Fr., 20. Nov. 2015 um 01:03 Uhr: > On 11/19/2015 03:57 PM, Philipp Stephani wrote: > > Thanks. I saw you changed some other members to ptrdiff_t (the public > > size members of emacs_runtime and emacs_env), is that intentional, and > > if so, what is the reason? > > As a general rule, in Emacs source code we prefer signed arithmetic to > unsigned, because the latter is so error prone when it comes to > comparisons. Also, signed arithmetic allows for better low-level > checking, e.g., with -fsanitize=undefined. (There are a few exceptions, > e.g., hash values, but they're relatively rare.) So the module > interface should encourage the use of signed integer arithmetic when > possible. > This is generally a good practice. However for the size members I think there's still a slight advantage in using size_t. This member will typically be used as follows: if (env->size >= sizeof *env) { // good, object is at least as big as expected } else { // Emacs is too old } The return type of sizeof is size_t. Using ptrdiff_t for the size member means that this is now a comparison between types of different signedness. Such comparisons are rather subtle, and compilers warn about them (e.g. clang with -Wextra). So I'd suggest th avoid such comparisons. As we never do any arithmetic with the size members, the wrap-around behavior is not an issue in this case. > > It might also be useful to support modules that, for whatever reason, > cannot deal with signed integers and must use unsigned integers. That > could be something we add later, if necessary. > I think we always expect a reasonably standard C or C++ compiler, which has to support signed integers. > > > Anyway, emacs-module.h now lacks an #include <stddef.h>. > > Thanks, fixed now. > [-- Attachment #2: Type: text/html, Size: 2554 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 19:29 ` Philipp Stephani @ 2015-11-20 20:47 ` Paul Eggert 2015-11-20 22:36 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-20 20:47 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel Cc: emacs-devel Philipp Stephani wrote: > This member will typically be used as follows: > > if (env->size >= sizeof *env) { > // good, object is at least as big as expected > } else { > // Emacs is too old > } I'm leery of recommending this sort of checking. In practice incompatible structure layout changes so often involve something more than merely extending a structure, that a size check is not worth the trouble; you really want a version check. I might be persuaded that it's a good idea if I saw some code doing it effectively, but currently there is no such code in the Emacs sources (the module test function doesn't check sizes -- why not?). ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 20:47 ` Paul Eggert @ 2015-11-20 22:36 ` Philipp Stephani 2015-11-20 23:06 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-20 22:36 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 1444 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am Fr., 20. Nov. 2015 um 21:48 Uhr: > Philipp Stephani wrote: > > This member will typically be used as follows: > > > > if (env->size >= sizeof *env) { > > // good, object is at least as big as expected > > } else { > > // Emacs is too old > > } > > > I'm leery of recommending this sort of checking. In practice incompatible > structure layout changes so often involve something more than merely > extending a > structure, that a size check is not worth the trouble; No such incompatible changes can be allowed to the emacs_env and emacs_runtime structures. Only additions at the end of the structures are allowed. This is independent of how the version checking is made. > you really want a version > check. I might be persuaded that it's a good idea See Daniel's initial design ( https://lists.gnu.org/archive/html/emacs-devel/2015-02/msg00960.html) for rationale. > if I saw some code doing it > effectively, but currently there is no such code in the Emacs sources Not inside Emacs, but e.g. the Windows API uses this approach extensively for version checking, and has been forward- and backward-compatible for decades with it. > (the > module test function doesn't check sizes -- why not?). > Just an omission, we'll fix that. All modules need to do version checks so they don't run into UB if they use a more recent emacs-module.h than the Emacs in which they are loaded. [-- Attachment #2: Type: text/html, Size: 2340 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 22:36 ` Philipp Stephani @ 2015-11-20 23:06 ` Paul Eggert 2015-11-21 8:54 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-20 23:06 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel Cc: emacs-devel Philipp Stephani wrote: > the Windows API uses this approach extensively > for version checking, and has been forward- and backward-compatible for > decades with it. This sort of approach might work in the MS-Windows world, which has a single dominant supplier. It's not clear that it would work in the GNU/Linux world, where different suppliers have different ABIs. And even if one takes exactly the same Emacs source and module source and runs on the same operating system, one can easily build Emacs executables that won't interoperate with modules, simply by using different compiler flags. The sizes might match, but the code won't. So I don't think sizes will suffice, at least, not outside of MS-Windows. Daniel's message pointed to JNI for an inspiration. JNI uses version numbers here (its GetVersion method), not sizes, I assume partly for the reasons discussed above. Shouldn't we do the same? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 23:06 ` Paul Eggert @ 2015-11-21 8:54 ` Philipp Stephani 2015-11-21 23:25 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-21 8:54 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 2510 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am Sa., 21. Nov. 2015 um 00:06 Uhr: > Philipp Stephani wrote: > > the Windows API uses this approach extensively > > for version checking, and has been forward- and backward-compatible for > > decades with it. > > This sort of approach might work in the MS-Windows world, which has a > single > dominant supplier. It's not clear that it would work in the GNU/Linux > world, > where different suppliers have different ABIs. And even if one takes > exactly > the same Emacs source and module source and runs on the same operating > system, > one can easily build Emacs executables that won't interoperate with > modules, > simply by using different compiler flags. Do you refer to different structure layouts due to padding differences? That would need to be ruled out somehow, maybe by making the padding explicit in emacs-module.h. I also don't see how version checks should be able to protect against this. If a module expects a structure member at a certain offset, it has to be placed at that offset. There is no way in C how to check for that at runtime. > The sizes might match, but the code > won't. So I don't think sizes will suffice, at least, not outside of > MS-Windows. > > I honestly can't think of a situation where version checking would work but size checking wouldn't. Given that users will use modules compiled with arbitrary versions of emacs-module.h together with arbitrary Emacsen, the following compatibility constraints have to be fulfilled: - Types of structure members may never change. - Structure members may never be reordered. - Structure members may never be removed. - New structure members can only be added at the end. Otherwise we'd need to export different versions of the structures and module authors would have to pick the correct version at runtime, which is more error-prone. Given these constraints, version number checks are equivalent to size checks. This isn't really related to Windows; these are ABI compatibility constraints that always occur when passing structures. > Daniel's message pointed to JNI for an inspiration. JNI uses version > numbers > here (its GetVersion method), not sizes, I assume partly for the reasons > discussed above. Shouldn't we do the same? Not necessarily. Daniel had good reasons to deviate from the JNI design in this respect: size checks are simpler and less error-prone because users don't need to remember or look up which member is present in which version. [-- Attachment #2: Type: text/html, Size: 3220 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 8:54 ` Philipp Stephani @ 2015-11-21 23:25 ` Paul Eggert 2015-11-22 9:15 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-21 23:25 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel Cc: emacs-devel Philipp Stephani wrote: > I honestly can't think of a situation where version checking would work but > size checking wouldn't. For example, a structure contains an off_t value, and time_t grows from 32 to 64-bits. The designer knew this might be a problem because of Y2038 issues, and so created padding for the time_t to grow into. Another example: suppose we change ptrdiff_t back to int. Another example: suppose we want the same module to work in both narrow and wide int Emacs, so we allocate storage for wide integers even though half of them are not used in narrow platforms. What you're saying, if I understand it, is that we promise that we'll never make any changes like that. This sounds overly constraining, at least for now. While the interface is experimental we'll retain the freedom to make arbitrary changes to it. When it settles down we can think about promises about never ever making changes in the future. In the meantime the size field is experimental and maybe we'll think of uses for it other than sizes. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 23:25 ` Paul Eggert @ 2015-11-22 9:15 ` Philipp Stephani 2015-11-22 18:37 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-22 9:15 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 2239 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am So., 22. Nov. 2015 um 00:25 Uhr: > Philipp Stephani wrote: > > I honestly can't think of a situation where version checking would work > but > > size checking wouldn't. > > For example, a structure contains an off_t value, and time_t grows from 32 > to > 64-bits. The designer knew this might be a problem because of Y2038 > issues, and > so created padding for the time_t to grow into. > > Another example: suppose we change ptrdiff_t back to int. > Such issues are why we generally prefer fixed-size integers. Currently the structures contain only pointers and pointer-sized integers. If we are careful to keep it that way, sizes can only ever increase. > > Another example: suppose we want the same module to work in both narrow > and wide > int Emacs, so we allocate storage for wide integers even though half of > them are > not used in narrow platforms. > The module interface never exposes Lisp_Objects directly, so it's immune to such considerations. > > What you're saying, if I understand it, is that we promise that we'll > never make > any changes like that. This sounds overly constraining, at least for now. > Not really, because there are no cases where we'd need to e.g. expose an off_t field. We only need three types of fields: - A field for version checking (size should be reasonably fixed) - A pointer-sized field pointing to private data (size is fixed within a single address space) - Function pointer fields for interacting with Emacs (size is fixed within the address space) If we ever need to expose an off_t value, it will be in the form of another function pointer. Even if, for whatever reason, we must expose an off_t value directly, we can insert appropriate padding to make sure the size increases. > While the interface is experimental we'll retain the freedom to make > arbitrary > changes to it. When it settles down we can think about promises about > never ever > making changes in the future. In the meantime the size field is > experimental and > maybe we'll think of uses for it other than sizes. > The module interface is supposed to be stable at least for the lifetime of Emacs 25. At least from our side it's not meant to be experimental. [-- Attachment #2: Type: text/html, Size: 3100 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 9:15 ` Philipp Stephani @ 2015-11-22 18:37 ` Paul Eggert 2015-11-22 19:17 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-22 18:37 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel Cc: emacs-devel I'm not going to belabor the point. If you want to use sizes as version numbers it's not worth fighting over. If we ever change a function API without changing the structure layout, I guess we'll have to insert a dummy structure member to make the size grow. Sounds like a kludge, but there are worse kludges in Emacs. Getting back to the original issue, your worry was that a ptrdiff_t size would lead to unnecessary warnings. I didn't get any such warning when compiling this with gcc -Wall: #include <stddef.h> ptrdiff_t size; int main (void) { return size < sizeof size; } I expect the warnings you're worried about occur when comparing an unknown ptrdiff_t with an unknown size_t; they should not occur when comparing an unknown ptrdiff_t with a size_t constant. If that's the case, let's leave it ptrdiff_t. And even if it's not the case, I'm inclined to leave it ptrdiff_t, as any module code will run into similar issues with the other ptrdiff_t components, so why make an exception for this one? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 18:37 ` Paul Eggert @ 2015-11-22 19:17 ` Philipp Stephani 0 siblings, 0 replies; 765+ messages in thread From: Philipp Stephani @ 2015-11-22 19:17 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii, Ted Zlatanov, Aurélien Aptel Cc: Daniel Colascione, Emacs developers [-- Attachment #1: Type: text/plain, Size: 1592 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am So., 22. Nov. 2015 um 19:38 Uhr: > I'm not going to belabor the point. If you want to use sizes as version > numbers > it's not worth fighting over. If we ever change a function API without > changing > the structure layout, I guess we'll have to insert a dummy structure > member to > make the size grow. Sounds like a kludge, but there are worse kludges in > Emacs. > Adding back Daniel. Not sure whether he follows this discussion, but he should definitely participate. > > Getting back to the original issue, your worry was that a ptrdiff_t size > would > lead to unnecessary warnings. I didn't get any such warning when > compiling this > with gcc -Wall: > > #include <stddef.h> > ptrdiff_t size; > > int main (void) { return size < sizeof size; } > > I expect the warnings you're worried about occur when comparing an unknown > ptrdiff_t with an unknown size_t; they should not occur when comparing an > unknown ptrdiff_t with a size_t constant. I get a warning with both Clang and GCC when compiling with -Wextra. > If that's the case, let's leave it > ptrdiff_t. And even if it's not the case, I'm inclined to leave it > ptrdiff_t, > as any module code will run into similar issues with the other ptrdiff_t > components, so why make an exception for this one? > What other ptrdiff_t components are there? The only other occurrences I see are the argument counts (which are never compared to sizes), and the string lengths (where callers might run into trouble if a buffer is larger than PTRDIFF_MAX, but that seems unlikely). [-- Attachment #2: Type: text/html, Size: 2265 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 22:41 ` Philipp Stephani 2015-11-19 23:51 ` Paul Eggert @ 2015-11-20 9:53 ` Eli Zaretskii 2015-11-20 11:59 ` Eli Zaretskii ` (3 more replies) 1 sibling, 4 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-20 9:53 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Thu, 19 Nov 2015 22:41:09 +0000 > Cc: emacs-devel@gnu.org > > Thanks for the thorough review; I'll prepare patches for all of these issues. Thank you. > This comment in module.c: > > /* If checking is enabled, abort if the current thread is not the > Emacs main thread. */ > static void check_main_thread (void); > > confused me, because a later comment says: > > void module_init (void) > { > /* It is not guaranteed that dynamic initializers run in the main thread, > therefore we detect the main thread here. */ > > If dynamic initializers might run in a thread different from the Emacs > main thread, then the code in module_init will record that other > thread, not the Emacs main thread, right? > > No, because module_init is guaranteed to be called from the main thread because > main calls it explicitly. So you are saying that module_init runs in the main thread, but dynamic initializers might run in another thread? How's that possible? > Also, another comment: > > /* On Windows, we store both a handle to the main thread and the > thread ID because the latter can be reused when a thread > terminates. */ > > seems to imply that 'main_thread' here is not the Emacs's main thread, > because that thread never terminates as long as the Emacs session is > alive. > > So what's the deal here? what does this thread checking supposed to > detect? > > This guards against the Emacs main thread having exited while module code in > some other thread is still running and attempting to call Emacs functions. On what OS can this happen? It cannot happen on Windows, AFAIK, so complicating the code by using a handle is not necessary on Windows, because the thread ID of the main Emacs thread will never be reused as long as the Emacs session is alive. Moreover, we already have that thread's ID in a global variable called dwMainThreadId, computed during the session startup (albeit after module_init, so it would need to be moved to an earlier stage), so we could simply compare against its value in check_main_thread. > This is undefined behavior, but we included an explicit check if > checking is enabled because that case is somewhat subtle. I'm surprised this could happen on some OS. Can you point to any details about this? > In this code from module.c: > > Lisp_Object value = HASH_VALUE (h, i); > eassert (NATNUMP (value)); > const EMACS_UINT refcount = XFASTINT (value); > if (refcount >= MOST_POSITIVE_FIXNUM) > { > module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); > return NULL; > } > > how can the 'if' clause ever be true? refcount is an Emacs integer, > as you have just verified, no? And if this somehow can happen, then > why isn't there a similar check in the other functions? > > refcount can be MOST_POSITIVE_FIXNUM because that's an inclusive bound. It's > important to check that case because later refcount is incremented by one, and > if it's equal to MOST_POSITIVE_FIXNUM it would be outside the allowed range > afterwards. No other function increments numbers, thus no other functions need > this check. OK, but then either there should have been a comment explaining this, or, better, the test should have been after the addition. (Which, by some strange luck -- or maybe something else -- is just what Paul already did ;-) > Re this fragment from module.c: > > Lisp_Object ret = list4 (Qlambda, > list2 (Qand_rest, Qargs), > documentation ? build_string (documentation) : Qnil, > list3 (module_call_func, > envobj, > Qargs)); > > Thou shalt not use build_string, except when you _know_ the argument > will always be a pure-ASCII string. Practically, this means the > argument must be a constant ASCII string. See these messages (and the > preceding discussion, if you are interested) for the gory details: > > http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00955.html > http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00976.html > http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00979.html > > The above should call make_multibyte_string instead. > > > We had a discussion about encodings in > https://github.com/aaptel/emacs-dynamic-module/issues/37. Sorry that this > didn't get resolved earlier; it's an important point. My suggestion would be to > always mandate specifying an encoding whenever a char* is passed, and limit > that to two or three functions dealing with creating strings and accessing > string contents. Would that address your concerns? No, this is not about encoding at all. This is about calling build_string: you should only call it when the argument is a fixed ASCII string. If the argument is not fixed or might include non-ASCII characters, you should call make_multibyte_string instead. That's because build_string might decide on its own whether to produce a unibyte or a multibyte string, out of your control, whereas we always want a multibyte string in this context. build_string doesn't encode or decode its argument, it creates a Lisp object whose text is taken from the argument. It's similar to make_number in that respect. > Again in module.c: > > /* > * Emacs internal encoding is more-or-less UTF8, let's assume utf8 > * encoded emacs string are the same byte size. > */ > > if (!buffer || length == 0 || *length-1 < raw_size) > { > *length = raw_size + 1; > return false; > } > > I don't understand why you need this assumption. You are going to > encode the string in a moment, so why not test 'length' against the > size you actually obtain there? (The above test will misfire when the > original string includes characters above the Unicode codespace, which > require 5 bytes internally, but their encoding maps them to Unicode > codepoints which cannot take more than 4 bytes. So you might reject > perfectly valid calls.) > > In module_make_string you have: > > /* Assume STR is utf8 encoded */ > return lisp_to_value (env, make_string (str, length)); > > The discussion I pointed to above concluded that <quote>make_string is > a bug</quote>. So please use make_multibyte_string here instead. > > > See above; my suggestion would be to change the string handling code by > limiting encoding and decoding to a small set of functions where the encoding > would have to be specified explicitly. Once again, that's not the issue. AFAIU, you have already specified (albeit implicitly) that all strings passed as arguments to and from the module functions are UTF-8 encoded. And that's fine by me, that's not what these comments are about. The first comment is about a minor issue in module_copy_string_contents. Consider this fragment from that function: ptrdiff_t raw_size = SBYTES (lisp_str); /* Emacs internal encoding is more-or-less UTF8, let's assume utf8 encoded emacs string are the same byte size. */ if (!buffer || length == 0 || *length-1 < raw_size) { *length = raw_size + 1; return false; } Lisp_Object lisp_str_utf8 = ENCODE_UTF_8 (lisp_str); eassert (raw_size == SBYTES (lisp_str_utf8)); *length = raw_size + 1; memcpy (buffer, SDATA (lisp_str_utf8), SBYTES (lisp_str_utf8)); buffer[raw_size] = 0; The comment and the 'if' clause after it in effect tell that you want to check whether 'buffer' has enough space to hold the encoded string, but you don't know how many bytes will be needed for that. So you make some assumption (which, as I pointed out, could be wrong in rare cases), and reject the strings that fail your test. What I'm sating is that after the call to ENCODE_UTF_8, you can compute the exact length in bytes of the UTF-8 encoded string, so if you move the test there, you won't have to make any assumptions and you won't err. The second comment is again about calling make_string (which build_string calls internally): use make_multibyte_string instead. > static void module_set_user_finalizer (emacs_env *env, > emacs_value uptr, > emacs_finalizer_function fin) > { > check_main_thread (); > eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return); > const Lisp_Object lisp = value_to_lisp (uptr); > if (! USER_PTRP (lisp)) module_wrong_type (env, Quser_ptr, lisp); > XUSER_PTR (lisp)->finalizer = fin; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< > } > > No validity checks on 'fin'? > > How should it be validated? In C an arbitrary (invalid) pointer could be > passed. I think we just have to accept that this is UB. Given the extensive checks elsewhere in the file, this surprised me, that's all. How to test it? calling valid_pointer_p would be one thing I'd suggest. Maybe there are other (perhaps platform-dependent) checks possible here, I would have to look around. For example, it would be good to make sure this points into executable code. > Shouldn't module-init call dynlib_close before it returns? Otherwise > we are leaking descriptors here, no? > > My impression from reading dlclose(3) is that modules shouldn't be unloaded > while they are still used. Yes, it was my mistake in understanding how the dynamic linking works in this case. Sorry. > if (len > INT_MAX || len < envptr->min_arity || (envptr->max_arity >= 0 && > len > envptr->max_arity)) > xsignal2 (Qwrong_number_of_arguments, module_format_fun_env (envptr), > make_number (len)); > > Why the test against INT_MAX? EMACS_INT can legitimately be a 64-bit > data type with values far exceeding INT_MAX. Why impose this > limitation here? > > Because the nargs argument in the module interface is an int. Shouldn't it be EMACS_INT instead? > If you think functions with more than INT_MAX arguments should be supported, > the type for nargs should be changed to int64. I thought your design decision was already to use int64 for any integer argument, no? Anyway, something that comes from Lisp should allow EMACS_INT, IMO. > allocate_emacs_value calls malloc; shouldn't it call xmalloc instead, > or at least conform to the XMALLOC_BLOCK_INPUT_CHECK protocol? > > If xmalloc is called, then we need to make sure that no signals (longjmps) can > escape to module code. If appropriate setjmps are in place that should be > doable, but I need to check whether there are edge cases. Paul already addressed that: xmalloc in Emacs does double or even triple duty, and it would be a shame to lose that here. So I think we should try to find a way to modify xmalloc such that it satisfies the module code as well. > Btw, I wonder whether we should provide a more friendly capabilities > for retrieving the function name and its module. dladdr is not > portable enough, and we have all the information at our fingertips > in the module's init function, we just need to keep it instead of > throwing it away. I envision debugging module-related problems will > not be a very rare situation, so we need any help we can get. WDYT? > > Hmm, I don't know whether we have access to the function name without using > dladdr. I thought about recording their names when you bind them to Lisp symbols. > About the tests: The Makefile in mod-test is Unix-specific: it uses a > literal .so extension. I also think the Python script should be > rewritten in Emacs Lisp, so that Python installation is not required. > Finally, all of the module tests and associated files should be moved > into test/, preferably even test/automated/ and made part of the "make > check" run. > > Yes, tracked in https://github.com/aaptel/emacs-dynamic-module/issues/34 You will see that I put there some preliminary stuff, so at least these tests can be run manually on Windows, by overriding a single Make variable from the command line. Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 9:53 ` Eli Zaretskii @ 2015-11-20 11:59 ` Eli Zaretskii 2015-11-20 15:52 ` Eli Zaretskii 2015-11-20 18:44 ` Paul Eggert ` (2 subsequent siblings) 3 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-20 11:59 UTC (permalink / raw) To: p.stephani2; +Cc: aurelien.aptel+emacs, tzz, emacs-devel One more comment: #elif defined HAVE_UNISTD_H /* POSIX systems. */ #include <dlfcn.h> This should probably use HAVE_DLFCN_H instead (computed by configure), instead of relying on unistd.h. Btw, 2 of the mod-test tests fail for me today; yesterday they all passed. I cannot see what could cause this, since all the relevant changes seem to me to be only reformatting and more or less trivial changes in data types. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 11:59 ` Eli Zaretskii @ 2015-11-20 15:52 ` Eli Zaretskii 2015-11-20 20:39 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-20 15:52 UTC (permalink / raw) To: Paul Eggert; +Cc: aurelien.aptel+emacs, p.stephani2, tzz, emacs-devel > Date: Fri, 20 Nov 2015 13:59:05 +0200 > From: Eli Zaretskii <eliz@gnu.org> > Cc: aurelien.aptel+emacs@gmail.com, tzz@lifelogs.com, emacs-devel@gnu.org > > Btw, 2 of the mod-test tests fail for me today; yesterday they all > passed. I cannot see what could cause this, since all the relevant > changes seem to me to be only reformatting and more or less trivial > changes in data types. I suspect the push_handlers changes in aa7dac8. It looks like signaling and throwing no longer works in a module. Paul, could you have a look? You should be able to see the problem by running the test in modules/mod-test/. Two tests there fail. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 15:52 ` Eli Zaretskii @ 2015-11-20 20:39 ` Paul Eggert 2015-11-20 21:22 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-20 20:39 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, p.stephani2, tzz, emacs-devel Eli Zaretskii wrote: > I suspect the push_handlers changes in aa7dac8. No, it was the reindenting change! I got confused by the do-while indenting in a complicated macro. Fixed in commit 95f69f2c5999be4b9444861b6d4ae1bd3ab87f83. I also noticed some int/ptrdiff_t issues in mod-test.c, and fixed them in commit 39d13206f3b37261bf4a2ebadfc1103414f4fd3e. Plus, I assume emacs_module_init is part of the module API? If so, it should be declared in emacs-module.h, which I did in commit d0e07e0e2239771fd21b9525ea421cf7ba1cc97c. I didn't notice all these problems because I wasn't running that test. I was just doing 'make check'. Philipp, shouldn't mod-test.c part of 'make check', when Emacs is configured --with-modules? Also, shouldn't the mod-test.c Makefile use the same GCC warning flags etc. that everyone else does? That would help catch these bugs better. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 20:39 ` Paul Eggert @ 2015-11-20 21:22 ` Eli Zaretskii 2015-11-20 22:46 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-20 21:22 UTC (permalink / raw) To: Paul Eggert; +Cc: aurelien.aptel+emacs, p.stephani2, tzz, emacs-devel > Cc: p.stephani2@gmail.com, aurelien.aptel+emacs@gmail.com, tzz@lifelogs.com, > emacs-devel@gnu.org > From: Paul Eggert <eggert@cs.ucla.edu> > Date: Fri, 20 Nov 2015 12:39:01 -0800 > > Eli Zaretskii wrote: > > I suspect the push_handlers changes in aa7dac8. > > No, it was the reindenting change! I got confused by the do-while indenting in a > complicated macro. Fixed in commit 95f69f2c5999be4b9444861b6d4ae1bd3ab87f83. Thanks, the tests now pass here as well. > I didn't notice all these problems because I wasn't running that test. I was > just doing 'make check'. Philipp, shouldn't mod-test.c part of 'make check', > when Emacs is configured --with-modules? Also, shouldn't the mod-test.c Makefile > use the same GCC warning flags etc. that everyone else does? That would help > catch these bugs better. Yes, on both counts. It's a matter of time to settle all that, though. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 21:22 ` Eli Zaretskii @ 2015-11-20 22:46 ` Philipp Stephani 0 siblings, 0 replies; 765+ messages in thread From: Philipp Stephani @ 2015-11-20 22:46 UTC (permalink / raw) To: Eli Zaretskii, Paul Eggert; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1192 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am Fr., 20. Nov. 2015 um 22:22 Uhr: > > Cc: p.stephani2@gmail.com, aurelien.aptel+emacs@gmail.com, > tzz@lifelogs.com, > > emacs-devel@gnu.org > > From: Paul Eggert <eggert@cs.ucla.edu> > > Date: Fri, 20 Nov 2015 12:39:01 -0800 > > > > Eli Zaretskii wrote: > > > I suspect the push_handlers changes in aa7dac8. > > > > No, it was the reindenting change! I got confused by the do-while > indenting in a > > complicated macro. Fixed in commit > 95f69f2c5999be4b9444861b6d4ae1bd3ab87f83. > > Thanks, the tests now pass here as well. > > > I didn't notice all these problems because I wasn't running that test. > I was > > just doing 'make check'. Philipp, shouldn't mod-test.c part of 'make > check', > > when Emacs is configured --with-modules? Also, shouldn't the mod-test.c > Makefile > > use the same GCC warning flags etc. that everyone else does? That would > help > > catch these bugs better. > > Yes, on both counts. It's a matter of time to settle all that, > though. > Absolutely! The tests should be no different from any other tests. There is https://github.com/aaptel/emacs-dynamic-module/issues/34, but we haven't gotten around to it yet. [-- Attachment #2: Type: text/html, Size: 1973 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 9:53 ` Eli Zaretskii 2015-11-20 11:59 ` Eli Zaretskii @ 2015-11-20 18:44 ` Paul Eggert 2015-11-20 18:50 ` Eli Zaretskii 2015-11-20 20:05 ` Philipp Stephani 2015-11-20 19:58 ` Philipp Stephani 2015-11-21 9:01 ` Philipp Stephani 3 siblings, 2 replies; 765+ messages in thread From: Paul Eggert @ 2015-11-20 18:44 UTC (permalink / raw) To: Eli Zaretskii, Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, emacs-devel Eli Zaretskii wrote: > I thought your design decision was already to use int64 for any > integer argument, no? I later changed that to use intmax_t for any integers that might be converted to or from Emacs fixnums. Function argument counts always must fit into ptrdiff_t, though, since the arg vector can't be larger than that, so it's OK to limit them to ptrdiff_t. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 18:44 ` Paul Eggert @ 2015-11-20 18:50 ` Eli Zaretskii 2015-11-20 19:13 ` Paul Eggert 2015-11-20 20:05 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-20 18:50 UTC (permalink / raw) To: Paul Eggert; +Cc: aurelien.aptel+emacs, p.stephani2, tzz, emacs-devel > Cc: aurelien.aptel+emacs@gmail.com, tzz@lifelogs.com, emacs-devel@gnu.org > From: Paul Eggert <eggert@cs.ucla.edu> > Date: Fri, 20 Nov 2015 10:44:01 -0800 > > Eli Zaretskii wrote: > > I thought your design decision was already to use int64 for any > > integer argument, no? > > I later changed that to use intmax_t for any integers that might be converted to > or from Emacs fixnums. Yes, okay. But intmax_t is a 64-bit type on most modern platforms, right? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 18:50 ` Eli Zaretskii @ 2015-11-20 19:13 ` Paul Eggert 0 siblings, 0 replies; 765+ messages in thread From: Paul Eggert @ 2015-11-20 19:13 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, p.stephani2, tzz, emacs-devel Eli Zaretskii wrote: > intmax_t is a 64-bit type on most modern platforms, > right? Yes, this is a no-op change for the platforms I know of. It's more future-proof, that's all. Neither C99 nor C11 nor even POSIX guarantee that int64_t is supported (this is for portability to mainframes with 72-bit longs, and I suppose to hypothetical future machines). Of course it's fine to use int64_t in platform-specific code where the platform guarantees that int64_t exists. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 18:44 ` Paul Eggert 2015-11-20 18:50 ` Eli Zaretskii @ 2015-11-20 20:05 ` Philipp Stephani 2015-11-20 20:32 ` Paul Eggert 1 sibling, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-20 20:05 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 645 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am Fr., 20. Nov. 2015 um 19:44 Uhr: > Eli Zaretskii wrote: > > I thought your design decision was already to use int64 for any > > integer argument, no? > > I later changed that to use intmax_t for any integers that might be > converted to > or from Emacs fixnums. Function argument counts always must fit into > ptrdiff_t, > though, since the arg vector can't be larger than that, so it's OK to > limit them > to ptrdiff_t. > Daniel felt pretty strongly about using int64 for fixnums. Is there any reason to change that? Right now the compile will just fail if Emacs fixnums don't fit into an int64. [-- Attachment #2: Type: text/html, Size: 952 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 20:05 ` Philipp Stephani @ 2015-11-20 20:32 ` Paul Eggert 2015-11-20 20:45 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-20 20:32 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel Philipp Stephani wrote: > Daniel felt pretty strongly about using int64 for fixnums. As I recall, he felt that we shouldn't use EMACS_INT in the module API, and int64_t was merely a means to that goal. If so, that's not a reason to prefer int64_t over intmax_t; it's merely a reason to make sure that intmax_t is at least as portable as int64_t is in this area. Which it is. > Is there any reason to change that? Yes, int64_t is not required by POSIX, C99, etc. That is, int64_t is an optional type. In contrast, intmax_t is required on all C99 platforms, and it has better support (e.g., there's a printf format specifier for it), so there are advantages to intmax_t over int64_t. I don't know of any advantage int64_t would have over intmax_t on any platform that Emacs supports. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 20:32 ` Paul Eggert @ 2015-11-20 20:45 ` Philipp Stephani 2015-11-20 20:59 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-20 20:45 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1107 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am Fr., 20. Nov. 2015 um 21:32 Uhr: > Philipp Stephani wrote: > > Daniel felt pretty strongly about using int64 for fixnums. > > As I recall, he felt that we shouldn't use EMACS_INT in the module API, and > int64_t was merely a means to that goal. If so, that's not a reason to > prefer > int64_t over intmax_t; it's merely a reason to make sure that intmax_t is > at > least as portable as int64_t is in this area. Which it is. > > > Is there any reason to change that? > > Yes, int64_t is not required by POSIX, C99, etc. That is, int64_t is an > optional type. In contrast, intmax_t is required on all C99 platforms, > and it > has better support (e.g., there's a printf format specifier for it), so > there > are advantages to intmax_t over int64_t. I don't know of any advantage > int64_t > would have over intmax_t on any platform that Emacs supports. > It would be guaranteed to always have the same size, if available. My understanding is that intmax_t could differ between compilers even on the same machine, which would silently break compatibility. [-- Attachment #2: Type: text/html, Size: 1444 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 20:45 ` Philipp Stephani @ 2015-11-20 20:59 ` Paul Eggert 2015-11-20 22:42 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-20 20:59 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel Philipp Stephani wrote: > intmax_t could differ between compilers even on the > same machine, which would silently break compatibility. Doesn't sound very likely. intmax_t is hardwired into the C library. If compilers disagree about its size, printf would stop working. Any incompatibility this extreme would require treating the different compilers like we treat any other differences in platform: you need to recompile your module. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 20:59 ` Paul Eggert @ 2015-11-20 22:42 ` Philipp Stephani 2015-11-20 23:44 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-20 22:42 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 837 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am Fr., 20. Nov. 2015 um 21:59 Uhr: > Philipp Stephani wrote: > > intmax_t could differ between compilers even on the > > same machine, which would silently break compatibility. > > Doesn't sound very likely. Maybe not likely, but not impossible. > intmax_t is hardwired into the C library. If > compilers disagree about its size, printf would stop working. It would still be possible to link against different C libraries. (However, that would probably break in other places.) > Any > incompatibility this extreme would require treating the different > compilers like > we treat any other differences in platform: you need to recompile your > module. > That might be true, though I'd like to wait for Daniel's assessment: as said, he felt quite strongly about not using intmax_t. [-- Attachment #2: Type: text/html, Size: 1440 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 22:42 ` Philipp Stephani @ 2015-11-20 23:44 ` Paul Eggert 2015-11-21 8:34 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-20 23:44 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel Philipp Stephani wrote: > Maybe not likely, but not impossible. I've never run into it, and have never heard of anyone running into it. In contrast, there are a few machines without int64_t -- though admittedly rare, we might as well not impose obstacles to porting to them if it's easy, which it is here. intmax_t is not the only alternative. We could also use 'long long int'. That's also portable to any C99 host, and should be just as well supported as intmax_t is (it has printf formats too). 'long long int' has been around for longer than intmax_t has, so in that sense it's a more-conservative choice. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 23:44 ` Paul Eggert @ 2015-11-21 8:34 ` Philipp Stephani 2015-11-23 17:06 ` Ted Zlatanov 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-21 8:34 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 847 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am Sa., 21. Nov. 2015 um 00:44 Uhr: > Philipp Stephani wrote: > > Maybe not likely, but not impossible. > > I've never run into it, and have never heard of anyone running into it. In > contrast, there are a few machines without int64_t -- though admittedly > rare, we > might as well not impose obstacles to porting to them if it's easy, which > it is > here. > > intmax_t is not the only alternative. We could also use 'long long int'. > That's > also portable to any C99 host, and should be just as well supported as > intmax_t > is (it has printf formats too). 'long long int' has been around for longer > than > intmax_t has, so in that sense it's a more-conservative choice. > I'm not feeling strongly about the exact type, but I'd suggest to wait for Daniel's input before making a final decision. [-- Attachment #2: Type: text/html, Size: 1191 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 8:34 ` Philipp Stephani @ 2015-11-23 17:06 ` Ted Zlatanov 0 siblings, 0 replies; 765+ messages in thread From: Ted Zlatanov @ 2015-11-23 17:06 UTC (permalink / raw) To: emacs-devel On Sat, 21 Nov 2015 08:34:16 +0000 Philipp Stephani <p.stephani2@gmail.com> wrote: PS> I'm not feeling strongly about the exact type, but I'd suggest to wait for PS> Daniel's input before making a final decision. I would ask John Wiegley to make the final decisions in those cases or to assign someone to make them for dynamic modules. Daniel is not available immediately (unless someone has a more direct way to contact him) and we clearly have enough expertise here. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 9:53 ` Eli Zaretskii 2015-11-20 11:59 ` Eli Zaretskii 2015-11-20 18:44 ` Paul Eggert @ 2015-11-20 19:58 ` Philipp Stephani 2015-11-20 21:56 ` Eli Zaretskii 2015-11-21 9:01 ` Philipp Stephani 3 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-20 19:58 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 14612 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am Fr., 20. Nov. 2015 um 10:54 Uhr: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Thu, 19 Nov 2015 22:41:09 +0000 > > Cc: emacs-devel@gnu.org > > > > Thanks for the thorough review; I'll prepare patches for all of these > issues. > > Thank you. > > > This comment in module.c: > > > > /* If checking is enabled, abort if the current thread is not the > > Emacs main thread. */ > > static void check_main_thread (void); > > > > confused me, because a later comment says: > > > > void module_init (void) > > { > > /* It is not guaranteed that dynamic initializers run in the main > thread, > > therefore we detect the main thread here. */ > > > > If dynamic initializers might run in a thread different from the > Emacs > > main thread, then the code in module_init will record that other > > thread, not the Emacs main thread, right? > > > > No, because module_init is guaranteed to be called from the main thread > because > > main calls it explicitly. > > So you are saying that module_init runs in the main thread, but > dynamic initializers might run in another thread? How's that > possible? > According to http://stackoverflow.com/a/29776416 it is not guaranteed that dynamic initializers run in the main thread. > > > Also, another comment: > > > > /* On Windows, we store both a handle to the main thread and the > > thread ID because the latter can be reused when a thread > > terminates. */ > > > > seems to imply that 'main_thread' here is not the Emacs's main > thread, > > because that thread never terminates as long as the Emacs session is > > alive. > > > > So what's the deal here? what does this thread checking supposed to > > detect? > > > > This guards against the Emacs main thread having exited while module > code in > > some other thread is still running and attempting to call Emacs > functions. > > On what OS can this happen? It cannot happen on Windows, AFAIK, http://blogs.msdn.com/b/oldnewthing/archive/2010/08/27/10054832.aspx seems to indicate that it is possible that other threads continue running after the main thread has exited. > so > complicating the code by using a handle is not necessary on Windows, > because the thread ID of the main Emacs thread will never be reused as > long as the Emacs session is alive. Moreover, we already have that > thread's ID in a global variable called dwMainThreadId, computed > during the session startup (albeit after module_init, so it would need > to be moved to an earlier stage), so we could simply compare against > its value in check_main_thread. > My initial code didn't use a thread identifier at all because it could have been reused after the main thread ended, introducing a subtle bug. > > > This is undefined behavior, but we included an explicit check if > > checking is enabled because that case is somewhat subtle. > > I'm surprised this could happen on some OS. Can you point to any > details about this? > It's not ruled out by the C standard or the APIs of operating systems. If Emacs doesn't call ExitThread or manipulates the C runtime, then indeed it can't happen (at least on Windows), but I think it's brittle to rely on such subtleties without explicitly checking for them (somebody might introduce a call to ExitThread in the future without looking at module code). > > > In this code from module.c: > > > > Lisp_Object value = HASH_VALUE (h, i); > > eassert (NATNUMP (value)); > > const EMACS_UINT refcount = XFASTINT (value); > > if (refcount >= MOST_POSITIVE_FIXNUM) > > { > > module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); > > return NULL; > > } > > > > how can the 'if' clause ever be true? refcount is an Emacs integer, > > as you have just verified, no? And if this somehow can happen, then > > why isn't there a similar check in the other functions? > > > > refcount can be MOST_POSITIVE_FIXNUM because that's an inclusive bound. > It's > > important to check that case because later refcount is incremented by > one, and > > if it's equal to MOST_POSITIVE_FIXNUM it would be outside the allowed > range > > afterwards. No other function increments numbers, thus no other > functions need > > this check. > > OK, but then either there should have been a comment explaining this, > or, better, the test should have been after the addition. (Which, by > some strange luck -- or maybe something else -- is just what Paul > already did ;-) > If the test gets moved after the addition, then we should have a verify(MAX_EMACS_UINT - 1 > MOST_POSITIVE_FIXNUM) or use __builtin_add_overflow to make sure the addition doesn't cause UB. > > > Re this fragment from module.c: > > > > Lisp_Object ret = list4 (Qlambda, > > list2 (Qand_rest, Qargs), > > documentation ? build_string (documentation) : Qnil, > > list3 (module_call_func, > > envobj, > > Qargs)); > > > > Thou shalt not use build_string, except when you _know_ the argument > > will always be a pure-ASCII string. Practically, this means the > > argument must be a constant ASCII string. See these messages (and the > > preceding discussion, if you are interested) for the gory details: > > > > > http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00955.html > > > http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00976.html > > > http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00979.html > > > > The above should call make_multibyte_string instead. > > > > > > We had a discussion about encodings in > > https://github.com/aaptel/emacs-dynamic-module/issues/37. Sorry that > this > > didn't get resolved earlier; it's an important point. My suggestion > would be to > > always mandate specifying an encoding whenever a char* is passed, and > limit > > that to two or three functions dealing with creating strings and > accessing > > string contents. Would that address your concerns? > > No, this is not about encoding at all. This is about calling > build_string: you should only call it when the argument is a fixed > ASCII string. If the argument is not fixed or might include non-ASCII > characters, you should call make_multibyte_string instead. That's > because build_string might decide on its own whether to produce a > unibyte or a multibyte string, out of your control, whereas we always > want a multibyte string in this context. > > build_string doesn't encode or decode its argument, it creates a Lisp > object whose text is taken from the argument. It's similar to > make_number in that respect. > I'll send a patch with my changes to explain my intention. > > > Again in module.c: > > > > /* > > * Emacs internal encoding is more-or-less UTF8, let's assume utf8 > > * encoded emacs string are the same byte size. > > */ > > > > if (!buffer || length == 0 || *length-1 < raw_size) > > { > > *length = raw_size + 1; > > return false; > > } > > > > I don't understand why you need this assumption. You are going to > > encode the string in a moment, so why not test 'length' against the > > size you actually obtain there? (The above test will misfire when the > > original string includes characters above the Unicode codespace, > which > > require 5 bytes internally, but their encoding maps them to Unicode > > codepoints which cannot take more than 4 bytes. So you might reject > > perfectly valid calls.) > > > > In module_make_string you have: > > > > /* Assume STR is utf8 encoded */ > > return lisp_to_value (env, make_string (str, length)); > > > > The discussion I pointed to above concluded that <quote>make_string > is > > a bug</quote>. So please use make_multibyte_string here instead. > > > > > > See above; my suggestion would be to change the string handling code by > > limiting encoding and decoding to a small set of functions where the > encoding > > would have to be specified explicitly. > > Once again, that's not the issue. AFAIU, you have already specified > (albeit implicitly) that all strings passed as arguments to and from > the module functions are UTF-8 encoded. And that's fine by me, that's > not what these comments are about. > > The first comment is about a minor issue in > module_copy_string_contents. Consider this fragment from that > function: > > ptrdiff_t raw_size = SBYTES (lisp_str); > > /* Emacs internal encoding is more-or-less UTF8, let's assume utf8 > encoded emacs string are the same byte size. */ > > if (!buffer || length == 0 || *length-1 < raw_size) > { > *length = raw_size + 1; > return false; > } > > Lisp_Object lisp_str_utf8 = ENCODE_UTF_8 (lisp_str); > eassert (raw_size == SBYTES (lisp_str_utf8)); > *length = raw_size + 1; > memcpy (buffer, SDATA (lisp_str_utf8), SBYTES (lisp_str_utf8)); > buffer[raw_size] = 0; > > The comment and the 'if' clause after it in effect tell that you want > to check whether 'buffer' has enough space to hold the encoded string, > but you don't know how many bytes will be needed for that. So you > make some assumption (which, as I pointed out, could be wrong in rare > cases), and reject the strings that fail your test. What I'm sating > is that after the call to ENCODE_UTF_8, you can compute the exact > length in bytes of the UTF-8 encoded string, so if you move the test > there, you won't have to make any assumptions and you won't err. > > The second comment is again about calling make_string (which > build_string calls internally): use make_multibyte_string instead. > > > static void module_set_user_finalizer (emacs_env *env, > > emacs_value uptr, > > emacs_finalizer_function fin) > > { > > check_main_thread (); > > eassert (module_non_local_exit_check (env) == > emacs_funcall_exit_return); > > const Lisp_Object lisp = value_to_lisp (uptr); > > if (! USER_PTRP (lisp)) module_wrong_type (env, Quser_ptr, lisp); > > XUSER_PTR (lisp)->finalizer = fin; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< > > } > > > > No validity checks on 'fin'? > > > > How should it be validated? In C an arbitrary (invalid) pointer could be > > passed. I think we just have to accept that this is UB. > > Given the extensive checks elsewhere in the file, this surprised me, > that's all. How to test it? calling valid_pointer_p would be one > thing I'd suggest. Maybe there are other (perhaps platform-dependent) > checks possible here, I would have to look around. For example, it > would be good to make sure this points into executable code. > You can't validate pointers in C. For example, is the following pointer valid? long a; double *p = (double *)(&a); The answer is no; this is an aliasing violation, and dereferencing p is UB, but you won't detect this by trying to read the process's address space. See also http://blogs.msdn.com/b/oldnewthing/archive/2006/09/27/773741.aspx. The best way to detect such issues is running under asan. > > > if (len > INT_MAX || len < envptr->min_arity || (envptr->max_arity > >= 0 && > > len > envptr->max_arity)) > > xsignal2 (Qwrong_number_of_arguments, module_format_fun_env (envptr), > > make_number (len)); > > > > Why the test against INT_MAX? EMACS_INT can legitimately be a 64-bit > > data type with values far exceeding INT_MAX. Why impose this > > limitation here? > > > > Because the nargs argument in the module interface is an int. > > Shouldn't it be EMACS_INT instead? > EMACS_INT is an internal type that isn't exposed to module authors. It should be either int or int64. > > > If you think functions with more than INT_MAX arguments should be > supported, > > the type for nargs should be changed to int64. > > I thought your design decision was already to use int64 for any > integer argument, no? > Daniel's initial design ( https://lists.gnu.org/archive/html/emacs-devel/2015-02/msg00960.html) had int, but I guess he wouldn't mind changing this to int64. > > Anyway, something that comes from Lisp should allow EMACS_INT, IMO. > It can't use EMACS_INT because that's an internal type defined in lisp.h, and emacs-module.h can't include lisp.h. Furthermore is should be a type with a static size to allow for ABI stability. Mismatches should be dealt with by explicit bounds checks. > > > allocate_emacs_value calls malloc; shouldn't it call xmalloc instead, > > or at least conform to the XMALLOC_BLOCK_INPUT_CHECK protocol? > > > > If xmalloc is called, then we need to make sure that no signals > (longjmps) can > > escape to module code. If appropriate setjmps are in place that should be > > doable, but I need to check whether there are edge cases. > > Paul already addressed that: xmalloc in Emacs does double or even > triple duty, and it would be a shame to lose that here. So I think we > should try to find a way to modify xmalloc such that it satisfies the > module code as well. > Could xmalloc grow a variant that is guaranteed not to call longjmp? > > > Btw, I wonder whether we should provide a more friendly capabilities > > for retrieving the function name and its module. dladdr is not > > portable enough, and we have all the information at our fingertips > > in the module's init function, we just need to keep it instead of > > throwing it away. I envision debugging module-related problems will > > not be a very rare situation, so we need any help we can get. WDYT? > > > > Hmm, I don't know whether we have access to the function name without > using > > dladdr. > > I thought about recording their names when you bind them to Lisp > symbols. > That would be nice, however it would require set_symbol_function, Fdefalias, etc. to explicitly check for module functions in their RHS. Not sure whether that's worth it. > > > About the tests: The Makefile in mod-test is Unix-specific: it uses a > > literal .so extension. I also think the Python script should be > > rewritten in Emacs Lisp, so that Python installation is not required. > > Finally, all of the module tests and associated files should be moved > > into test/, preferably even test/automated/ and made part of the > "make > > check" run. > > > > Yes, tracked in https://github.com/aaptel/emacs-dynamic-module/issues/34 > > You will see that I put there some preliminary stuff, so at least > these tests can be run manually on Windows, by overriding a single > Make variable from the command line. > > Thanks. > [-- Attachment #2: Type: text/html, Size: 19777 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 19:58 ` Philipp Stephani @ 2015-11-20 21:56 ` Eli Zaretskii 2015-11-20 23:22 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-20 21:56 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Fri, 20 Nov 2015 19:58:25 +0000 > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, emacs-devel@gnu.org > > So you are saying that module_init runs in the main thread, but > dynamic initializers might run in another thread? How's that > possible? > > According to http://stackoverflow.com/a/29776416 it is not guaranteed that > dynamic initializers run in the main thread. Ah, you are talking about C++ dynamic initializers! So the model is that someone writes a module in C++, starts a thread there, and then inside some dynamic initializer calls emacs-module interface functions, is that it? If that's the situation, I'd suggest a prominent commentary describing this in the source. > On what OS can this happen? It cannot happen on Windows, AFAIK, > > http://blogs.msdn.com/b/oldnewthing/archive/2010/08/27/10054832.aspx seems to > indicate that it is possible that other threads continue running after the main > thread has exited. Not in Emacs: we use the C runtime, and never call ExitThread, let alone ExitProcess. Doing that would be a silly bug. There's no need to make a single component of Emacs, and not the most important one, protected to such extreme degree against calamities that are only possible if Emacs developers will lose their senses. > My initial code didn't use a thread identifier at all because it could have > been reused after the main thread ended, introducing a subtle bug. No, it cannot be reused, because we hold a handle on the main thread, see w32term.c around line 6985. As long as a single handle is open on a thread, it still exists from the OS POV, and its ID cannot be reused. > > This is undefined behavior, but we included an explicit check if > > checking is enabled because that case is somewhat subtle. > > I'm surprised this could happen on some OS. Can you point to any > details about this? > > > It's not ruled out by the C standard or the APIs of operating systems. If Emacs > doesn't call ExitThread or manipulates the C runtime, then indeed it can't > happen (at least on Windows), but I think it's brittle to rely on such > subtleties without explicitly checking for them (somebody might introduce a > call to ExitThread in the future without looking at module code). I think these precautions are unnecessary. Anyway, thanks for explaining this, I now know how to change the code to DTRT on MS-Windows wrt to the thread checks. > OK, but then either there should have been a comment explaining this, > or, better, the test should have been after the addition. (Which, by > some strange luck -- or maybe something else -- is just what Paul > already did ;-) > > If the test gets moved after the addition, then we should have a verify > (MAX_EMACS_UINT - 1 > MOST_POSITIVE_FIXNUM) or use __builtin_add_overflow to > make sure the addition doesn't cause UB. I don't think so. Please take a look at the code Paul wrote there, I don't see a problem with it. > > No validity checks on 'fin'? > > > > How should it be validated? In C an arbitrary (invalid) pointer could be > > passed. I think we just have to accept that this is UB. > > Given the extensive checks elsewhere in the file, this surprised me, > that's all. How to test it? calling valid_pointer_p would be one > thing I'd suggest. Maybe there are other (perhaps platform-dependent) > checks possible here, I would have to look around. For example, it > would be good to make sure this points into executable code. > > You can't validate pointers in C. For example, is the following pointer valid? > > long a; > double *p = (double *)(&a); > > The answer is no; this is an aliasing violation, and dereferencing p is UB, but > you won't detect this by trying to read the process's address space. The function valid_pointer_p validates a pointer in the sense that it points into the program's address space. That's not a full validation, and won't catch unaligned pointers or pointers into non-executable portions of memory, but it's better than nothing. I'd certainly consider it under "#ifdef ENABLE_CHECKING" at least. > See also > http://blogs.msdn.com/b/oldnewthing/archive/2006/09/27/773741.aspx. We don't use IsBadWritePtr on Windows to check this, see w32_valid_pointer_p for how this is actually implemented. Anyway, I'm surprised by this extreme POV: even if we cannot validate a pointer 100%, surely it doesn't mean we cannot or shouldn't do some partial job? Why this "all or nothing" approach? > > if (len > INT_MAX || len < envptr->min_arity || (envptr->max_arity >= 0 > && > > len > envptr->max_arity)) > > xsignal2 (Qwrong_number_of_arguments, module_format_fun_env (envptr), > > make_number (len)); > > > > Why the test against INT_MAX? EMACS_INT can legitimately be a 64-bit > > data type with values far exceeding INT_MAX. Why impose this > > limitation here? > > > > Because the nargs argument in the module interface is an int. > > Shouldn't it be EMACS_INT instead? > > EMACS_INT is an internal type that isn't exposed to module authors. OK, but the type of nargs is ptrdiff_t, so the test should be against the maximum of that type. On 64-bit hosts, ptrdiff_t is a 64-bit type, while an int is still 32-bit wide. > Could xmalloc grow a variant that is guaranteed not to call longjmp? We need to devise a way for it to detect that it was called from emacs-module.c, the rest is simple, I think. Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 21:56 ` Eli Zaretskii @ 2015-11-20 23:22 ` Philipp Stephani 2015-11-20 23:29 ` Paul Eggert 2015-11-21 8:35 ` Eli Zaretskii 0 siblings, 2 replies; 765+ messages in thread From: Philipp Stephani @ 2015-11-20 23:22 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 7962 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am Fr., 20. Nov. 2015 um 22:56 Uhr: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Fri, 20 Nov 2015 19:58:25 +0000 > > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, > emacs-devel@gnu.org > > > > So you are saying that module_init runs in the main thread, but > > dynamic initializers might run in another thread? How's that > > possible? > > > > According to http://stackoverflow.com/a/29776416 it is not guaranteed > that > > dynamic initializers run in the main thread. > > Ah, you are talking about C++ dynamic initializers! So the model is > that someone writes a module in C++, starts a thread there, and then > inside some dynamic initializer calls emacs-module interface > functions, is that it? If that's the situation, I'd suggest a > prominent commentary describing this in the source. > The SO post talks about C++ but the issue is the same in C. AFAIK with C11 and C++11 the execution models are harmonized. It seems the comment is overly confusing. It is supposed to warn about the following. Naively, if you wanted to test whether you are in the main thread, you would do (module types and naming): static thread_id main_thread = get_current_thread(); bool in_main_thread() { return get_current_thread() == main_thread; } The dynamic initializer here is the first "get_current_thread()"; it is not guaranteed to run in the main thread, so "main_thread" is not guaranteed to contain the main thread ID. Therefore you have to do: static thread_id main_thread; // initialized later int main() { // guaranteed to be in the main thread main_thread = get_current_thread(); } That's all. I'm not aware of any runtime that would run dynamic initializers outside of the main thread, but it's not impossible and easy to protect against. > > > On what OS can this happen? It cannot happen on Windows, AFAIK, > > > > http://blogs.msdn.com/b/oldnewthing/archive/2010/08/27/10054832.aspx > seems to > > indicate that it is possible that other threads continue running after > the main > > thread has exited. > > Not in Emacs: we use the C runtime, and never call ExitThread, let > alone ExitProcess. Doing that would be a silly bug. There's no need > to make a single component of Emacs, and not the most important one, > protected to such extreme degree against calamities that are only > possible if Emacs developers will lose their senses. > Fair enough. We can replace this with a comment ("assume no more threads are running after main has exited") if you prefer that. > > > My initial code didn't use a thread identifier at all because it could > have > > been reused after the main thread ended, introducing a subtle bug. > > No, it cannot be reused, because we hold a handle on the main thread, > see w32term.c around line 6985. As long as a single handle is open on > a thread, it still exists from the OS POV, and its ID cannot be > reused. > > > > This is undefined behavior, but we included an explicit check if > > > checking is enabled because that case is somewhat subtle. > > > > I'm surprised this could happen on some OS. Can you point to any > > details about this? > > > > > > It's not ruled out by the C standard or the APIs of operating systems. > If Emacs > > doesn't call ExitThread or manipulates the C runtime, then indeed it > can't > > happen (at least on Windows), but I think it's brittle to rely on such > > subtleties without explicitly checking for them (somebody might > introduce a > > call to ExitThread in the future without looking at module code). > > I think these precautions are unnecessary. > > Anyway, thanks for explaining this, I now know how to change the code > to DTRT on MS-Windows wrt to the thread checks. > This is unfortunately all surprisingly subtle and vaguely defined. See e.g. http://stackoverflow.com/q/19744250/178761 (apparently the standards are vague about what happens to detached threads after main has exited). > > > OK, but then either there should have been a comment explaining this, > > or, better, the test should have been after the addition. (Which, by > > some strange luck -- or maybe something else -- is just what Paul > > already did ;-) > > > > If the test gets moved after the addition, then we should have a verify > > (MAX_EMACS_UINT - 1 > MOST_POSITIVE_FIXNUM) or use > __builtin_add_overflow to > > make sure the addition doesn't cause UB. > > I don't think so. Please take a look at the code Paul wrote there, I > don't see a problem with it. > There is no problem with the code, but reading it requires knowledge that there are tag bits, which prevent a possible signed overflow. A verify would be a compiler-checked comment for that. > > > > No validity checks on 'fin'? > > > > > > How should it be validated? In C an arbitrary (invalid) pointer > could be > > > passed. I think we just have to accept that this is UB. > > > > Given the extensive checks elsewhere in the file, this surprised me, > > that's all. How to test it? calling valid_pointer_p would be one > > thing I'd suggest. Maybe there are other (perhaps platform-dependent) > > checks possible here, I would have to look around. For example, it > > would be good to make sure this points into executable code. > > > > You can't validate pointers in C. For example, is the following pointer > valid? > > > > long a; > > double *p = (double *)(&a); > > > > The answer is no; this is an aliasing violation, and dereferencing p is > UB, but > > you won't detect this by trying to read the process's address space. > > The function valid_pointer_p validates a pointer in the sense that it > points into the program's address space. That's not a full > validation, and won't catch unaligned pointers or pointers into > non-executable portions of memory, but it's better than nothing. I'd > certainly consider it under "#ifdef ENABLE_CHECKING" at least. > We can add that for consistency, though I'm not sure whether such checks don't do more harm than good. > > > See also > > http://blogs.msdn.com/b/oldnewthing/archive/2006/09/27/773741.aspx. > > We don't use IsBadWritePtr on Windows to check this, see > w32_valid_pointer_p for how this is actually implemented. > > Much of this applies generally. > "But what should I do, then, if somebody passes me a bad pointer?" > You should crash. > Anyway, I'm surprised by this extreme POV: even if we cannot validate > a pointer 100%, surely it doesn't mean we cannot or shouldn't do some > partial job? Why this "all or nothing" approach? > We can check whether it's NULL. Apart from that, everything else is outside of the C standard. > > > > if (len > INT_MAX || len < envptr->min_arity || (envptr->max_arity > >= 0 > > && > > > len > envptr->max_arity)) > > > xsignal2 (Qwrong_number_of_arguments, module_format_fun_env > (envptr), > > > make_number (len)); > > > > > > Why the test against INT_MAX? EMACS_INT can legitimately be a > 64-bit > > > data type with values far exceeding INT_MAX. Why impose this > > > limitation here? > > > > > > Because the nargs argument in the module interface is an int. > > > > Shouldn't it be EMACS_INT instead? > > > > EMACS_INT is an internal type that isn't exposed to module authors. > > OK, but the type of nargs is ptrdiff_t, so the test should be against > the maximum of that type. On 64-bit hosts, ptrdiff_t is a 64-bit > type, while an int is still 32-bit wide. > Yes, the type is *now* ptrdiff_t. It was int when I wrote the code :-) > > > Could xmalloc grow a variant that is guaranteed not to call longjmp? > > We need to devise a way for it to detect that it was called from > emacs-module.c, the rest is simple, I think. > > Hmm, why does it need to detect anything? Can't it just be a different function that doesn't signal, similar to push_handler and push_handler_nosignal? [-- Attachment #2: Type: text/html, Size: 11254 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 23:22 ` Philipp Stephani @ 2015-11-20 23:29 ` Paul Eggert 2015-11-21 0:08 ` Philipp Stephani 2015-11-21 8:35 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-20 23:29 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel Philipp Stephani wrote: > why does it need to detect anything? Can't it just be a different > function that doesn't signal, similar to push_handler and > push_handler_nosignal? Yes, that should work and should be easy to implement. But how would it behave to the caller? Will the caller have to check that it doesn't return NULL? I hope not; that would be a pain and error-prone. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 23:29 ` Paul Eggert @ 2015-11-21 0:08 ` Philipp Stephani 2015-11-21 0:28 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-21 0:08 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 518 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am Sa., 21. Nov. 2015 um 00:29 Uhr: > Philipp Stephani wrote: > > why does it need to detect anything? Can't it just be a different > > function that doesn't signal, similar to push_handler and > > push_handler_nosignal? > > Yes, that should work and should be easy to implement. But how would it > behave > to the caller? Will the caller have to check that it doesn't return NULL? > I hope > not; that would be a pain and error-prone. > Why, that's how malloc also behaves. [-- Attachment #2: Type: text/html, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 0:08 ` Philipp Stephani @ 2015-11-21 0:28 ` Paul Eggert 2015-11-21 8:33 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-21 0:28 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel Philipp Stephani wrote: > Why, that's how malloc also behaves. Yes, of course. But this part of malloc's behavior is so painful that Emacs code typically never invokes malloc directly; it uses xmalloc, which is guaranteed to return non-null. Many modules will have needs similar to Emacs itself in that respect, and it would be better if they didn't have to reinvent this so-common wheel. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 0:28 ` Paul Eggert @ 2015-11-21 8:33 ` Philipp Stephani 2015-11-21 23:10 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-21 8:33 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 931 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am Sa., 21. Nov. 2015 um 01:28 Uhr: > Philipp Stephani wrote: > > Why, that's how malloc also behaves. > > Yes, of course. But this part of malloc's behavior is so painful that > Emacs code > typically never invokes malloc directly; it uses xmalloc, which is > guaranteed to > return non-null. Many modules will have needs similar to Emacs itself in > that > respect, and it would be better if they didn't have to reinvent this > so-common > wheel. > But what should the interface be? There are only three possibilities in C: return a sentinel value, crash, longjmp. Crashing prevents modules from doing their own error handling or degrading gracefully. longjmp is not possible in general because arbitrary C (and especially C++) code isn't prepared for it. So the sentinel value is the only option. This is also consistent with all the other environment functions that return a pointer. [-- Attachment #2: Type: text/html, Size: 1236 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 8:33 ` Philipp Stephani @ 2015-11-21 23:10 ` Paul Eggert 2015-11-22 9:03 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-21 23:10 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel Philipp Stephani wrote: >> Many modules will have needs similar to Emacs itself in >> >that >> >respect, and it would be better if they didn't have to reinvent this >> >so-common >> >wheel. >> > > But what should the interface be? There are only three possibilities in C: > return a sentinel value, crash, longjmp. There's a fourth possibility: do what Emacs does. Emacs defines its own throw-catch mechanism built atop C. C modules that need to cleanup when unwound can do so by registering via the equivalent of record_unwind_protect, and Emacs won't longjmp through them without cleaning up. This already works for xmalloc memory-exhaustion failures, and modules can just use the already-existing mechanism. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 23:10 ` Paul Eggert @ 2015-11-22 9:03 ` Philipp Stephani 2015-11-22 16:23 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-22 9:03 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1465 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am So., 22. Nov. 2015 um 00:10 Uhr: > Philipp Stephani wrote: > >> Many modules will have needs similar to Emacs itself in > >> >that > >> >respect, and it would be better if they didn't have to reinvent this > >> >so-common > >> >wheel. > >> > > > But what should the interface be? There are only three possibilities in > C: > > return a sentinel value, crash, longjmp. > > There's a fourth possibility: do what Emacs does. Emacs defines its own > throw-catch mechanism built atop C. C modules that need to cleanup when > unwound > can do so by registering via the equivalent of record_unwind_protect, and > Emacs > won't longjmp through them without cleaning up. This already works for > xmalloc > memory-exhaustion failures, and modules can just use the already-existing > mechanism. > We have already discussed longjmp at length in this thread, and Daniel, Aurélien and I are all strongly against it. Using longjmp makes it effectively impossible to write modules in any language but C, and even C code has to be very careful (e.g. it can't use __attribute__((cleanup))). longjmp is only possible within a monolithic system that is able to make closed-world assumptions such as the Emacs binary itself, it is impossible in generic and portable library code. We have worked hard to remove the possibility of longjmp leaking into module code, and I won't put that possibility back in. [-- Attachment #2: Type: text/html, Size: 1815 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 9:03 ` Philipp Stephani @ 2015-11-22 16:23 ` Eli Zaretskii 2015-11-22 16:27 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-22 16:23 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, eggert, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sun, 22 Nov 2015 09:03:39 +0000 > Cc: aurelien.aptel+emacs@gmail.com, tzz@lifelogs.com, emacs-devel@gnu.org > > We have already discussed longjmp at length in this thread, and Daniel, > Aurélien and I are all strongly against it. Using longjmp makes it effectively > impossible to write modules in any language but C, and even C code has to be > very careful (e.g. it can't use __attribute__((cleanup))). longjmp is only > possible within a monolithic system that is able to make closed-world > assumptions such as the Emacs binary itself, it is impossible in generic and > portable library code. We have worked hard to remove the possibility of longjmp > leaking into module code, and I won't put that possibility back in. I don't understand: we already have in emacs-module.c machinery that handles non-local exits. Why cannot xmalloc do the same when it's called from emacs-module.c? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 16:23 ` Eli Zaretskii @ 2015-11-22 16:27 ` Philipp Stephani 2015-11-22 16:56 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-22 16:27 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, eggert, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1266 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am So., 22. Nov. 2015 um 17:23 Uhr: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Sun, 22 Nov 2015 09:03:39 +0000 > > Cc: aurelien.aptel+emacs@gmail.com, tzz@lifelogs.com, > emacs-devel@gnu.org > > > > We have already discussed longjmp at length in this thread, and Daniel, > > Aurélien and I are all strongly against it. Using longjmp makes it > effectively > > impossible to write modules in any language but C, and even C code has > to be > > very careful (e.g. it can't use __attribute__((cleanup))). longjmp is > only > > possible within a monolithic system that is able to make closed-world > > assumptions such as the Emacs binary itself, it is impossible in generic > and > > portable library code. We have worked hard to remove the possibility of > longjmp > > leaking into module code, and I won't put that possibility back in. > > I don't understand: we already have in emacs-module.c machinery that > handles non-local exits. Why cannot xmalloc do the same when it's > called from emacs-module.c? > My impression was that Paul talked about code in modules, not code in emacs-module.c. The latter can use xmalloc just fine, if appropriate protection is installed first. [-- Attachment #2: Type: text/html, Size: 1836 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 16:27 ` Philipp Stephani @ 2015-11-22 16:56 ` Eli Zaretskii 2015-11-22 17:18 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-22 16:56 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, eggert, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sun, 22 Nov 2015 16:27:19 +0000 > Cc: eggert@cs.ucla.edu, aurelien.aptel+emacs@gmail.com, tzz@lifelogs.com, > emacs-devel@gnu.org > > Eli Zaretskii <eliz@gnu.org> schrieb am So., 22. Nov. 2015 um 17:23 Uhr: > > I don't understand: we already have in emacs-module.c machinery that > handles non-local exits. Why cannot xmalloc do the same when it's > called from emacs-module.c? > > My impression was that Paul talked about code in modules, not code in > emacs-module.c. The latter can use xmalloc just fine, if appropriate protection > is installed first. I'll let Paul explain what he was worried about. What I was worried about is that memory allocation done by emacs-module.c on behalf of modules doesn't behave like xmalloc does, doesn't comply to the MALLOC_BLOCK_INPUT protocol, and cannot be probed by MALLOC_PROBE. I think this should be easy to fix. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 16:56 ` Eli Zaretskii @ 2015-11-22 17:18 ` Philipp Stephani 2015-11-22 17:27 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-22 17:18 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, eggert, emacs-devel [-- Attachment #1.1: Type: text/plain, Size: 1087 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am So., 22. Nov. 2015 um 17:56 Uhr: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Sun, 22 Nov 2015 16:27:19 +0000 > > Cc: eggert@cs.ucla.edu, aurelien.aptel+emacs@gmail.com, tzz@lifelogs.com > , > > emacs-devel@gnu.org > > > > Eli Zaretskii <eliz@gnu.org> schrieb am So., 22. Nov. 2015 um 17:23 Uhr: > > > > I don't understand: we already have in emacs-module.c machinery that > > handles non-local exits. Why cannot xmalloc do the same when it's > > called from emacs-module.c? > > > > My impression was that Paul talked about code in modules, not code in > > emacs-module.c. The latter can use xmalloc just fine, if appropriate > protection > > is installed first. > > I'll let Paul explain what he was worried about. What I was worried > about is that memory allocation done by emacs-module.c on behalf of > modules doesn't behave like xmalloc does, doesn't comply to the > MALLOC_BLOCK_INPUT protocol, and cannot be probed by MALLOC_PROBE. I > think this should be easy to fix. > > Yes, I've attached a patch. [-- Attachment #1.2: Type: text/html, Size: 1850 bytes --] [-- Attachment #2: 0001-Use-xmalloc-in-module-code.patch --] [-- Type: application/octet-stream, Size: 3862 bytes --] From 1511fab973d0c054f4279f857412ae0f3dee28ae Mon Sep 17 00:00:00 2001 From: Philipp Stephani <phst@google.com> Date: Sun, 22 Nov 2015 18:14:22 +0100 Subject: [PATCH] Use xmalloc in module code --- src/emacs-module.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/emacs-module.c b/src/emacs-module.c index 84072b9..8705280 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -136,7 +136,7 @@ struct module_fun_env; static Lisp_Object module_format_fun_env (const struct module_fun_env *); static Lisp_Object value_to_lisp (emacs_value); -static emacs_value allocate_emacs_value (emacs_env *, struct emacs_value_storage *, Lisp_Object); +static emacs_value allocate_emacs_value (struct emacs_value_storage *, Lisp_Object); static emacs_value lisp_to_value (emacs_env *, Lisp_Object); static enum emacs_funcall_exit module_non_local_exit_check (emacs_env *); static void check_main_thread (void); @@ -284,7 +284,7 @@ module_make_global_ref (emacs_env *env, emacs_value ref) hash_put (h, new_obj, make_natnum (1), hashcode); } - return allocate_emacs_value (env, &global_storage, new_obj); + return allocate_emacs_value (&global_storage, new_obj); } static void @@ -440,6 +440,7 @@ module_type_of (emacs_env *env, emacs_value value) { check_main_thread (); eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return); + MODULE_HANDLE_SIGNALS; return lisp_to_value (env, Ftype_of (value_to_lisp (value))); } @@ -478,6 +479,7 @@ module_make_integer (emacs_env *env, intmax_t n) { check_main_thread (); eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return); + MODULE_HANDLE_SIGNALS; if (! (MOST_NEGATIVE_FIXNUM <= n && n <= MOST_POSITIVE_FIXNUM)) { module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); @@ -850,18 +852,21 @@ module_args_out_of_range (emacs_env *env, Lisp_Object a1, Lisp_Object a2) static Lisp_Object value_to_lisp (emacs_value v) { + eassert (v != NULL); return v->v; } /* Convert an internal object to an `emacs_value'. Allocate storage - from the environment; return NULL if allocation fails. */ + from the environment; raise a signal if allocation fails. */ static emacs_value lisp_to_value (emacs_env *env, Lisp_Object o) { + eassert (env != NULL); struct emacs_env_private *p = env->private_members; + // TODO: Remove the next statement. if (p->pending_non_local_exit != emacs_funcall_exit_return) return NULL; - return allocate_emacs_value (env, &p->storage, o); + return allocate_emacs_value (&p->storage, o); } \f @@ -898,23 +903,19 @@ finalize_storage (struct emacs_value_storage *storage) } } -/* Allocate a new value from STORAGE and stores OBJ in it. Return - NULL if allocations fails and use ENV for non local exit reporting. */ +/* Allocate a new value from STORAGE and stores OBJ in it. Signal an + error if allocation fails. */ static emacs_value -allocate_emacs_value (emacs_env *env, struct emacs_value_storage *storage, +allocate_emacs_value (struct emacs_value_storage *storage, Lisp_Object obj) { - eassert (storage->current); + eassert (storage != NULL); + eassert (storage->current != NULL); eassert (storage->current->offset < value_frame_size); - eassert (! storage->current->next); + eassert (storage->current->next == NULL); if (storage->current->offset == value_frame_size - 1) { - storage->current->next = malloc (sizeof *storage->current->next); - if (! storage->current->next) - { - module_out_of_memory (env); - return NULL; - } + storage->current->next = xmalloc (sizeof *storage->current->next); initialize_frame (storage->current->next); storage->current = storage->current->next; } -- 2.6.3 ^ permalink raw reply related [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 17:18 ` Philipp Stephani @ 2015-11-22 17:27 ` Philipp Stephani 2015-11-22 18:50 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-22 17:27 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, eggert, emacs-devel [-- Attachment #1.1: Type: text/plain, Size: 1249 bytes --] Another one containing changelog entries. Philipp Stephani <p.stephani2@gmail.com> schrieb am So., 22. Nov. 2015 um 18:18 Uhr: > Eli Zaretskii <eliz@gnu.org> schrieb am So., 22. Nov. 2015 um 17:56 Uhr: > >> > From: Philipp Stephani <p.stephani2@gmail.com> >> > Date: Sun, 22 Nov 2015 16:27:19 +0000 >> > Cc: eggert@cs.ucla.edu, aurelien.aptel+emacs@gmail.com, >> tzz@lifelogs.com, >> > emacs-devel@gnu.org >> > >> > Eli Zaretskii <eliz@gnu.org> schrieb am So., 22. Nov. 2015 um 17:23 >> Uhr: >> > >> > I don't understand: we already have in emacs-module.c machinery that >> > handles non-local exits. Why cannot xmalloc do the same when it's >> > called from emacs-module.c? >> > >> > My impression was that Paul talked about code in modules, not code in >> > emacs-module.c. The latter can use xmalloc just fine, if appropriate >> protection >> > is installed first. >> >> I'll let Paul explain what he was worried about. What I was worried >> about is that memory allocation done by emacs-module.c on behalf of >> modules doesn't behave like xmalloc does, doesn't comply to the >> MALLOC_BLOCK_INPUT protocol, and cannot be probed by MALLOC_PROBE. I >> think this should be easy to fix. >> >> > Yes, I've attached a patch. > [-- Attachment #1.2: Type: text/html, Size: 2285 bytes --] [-- Attachment #2: 0001-Use-xmalloc-in-module-code.patch --] [-- Type: application/octet-stream, Size: 4057 bytes --] From 81b711aaf0d967f7c20ce8453afb0cfbef5e58e5 Mon Sep 17 00:00:00 2001 From: Philipp Stephani <phst@google.com> Date: Sun, 22 Nov 2015 18:14:22 +0100 Subject: [PATCH] Use xmalloc in module code * emacs-module.c (allocate_emacs_value): Use xmalloc instead of malloc. (module_type_of, module_make_integer): Catch signals. (lisp_to_value, module_make_global_ref): Adapt to changed interface. --- src/emacs-module.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/emacs-module.c b/src/emacs-module.c index 84072b9..8705280 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -136,7 +136,7 @@ struct module_fun_env; static Lisp_Object module_format_fun_env (const struct module_fun_env *); static Lisp_Object value_to_lisp (emacs_value); -static emacs_value allocate_emacs_value (emacs_env *, struct emacs_value_storage *, Lisp_Object); +static emacs_value allocate_emacs_value (struct emacs_value_storage *, Lisp_Object); static emacs_value lisp_to_value (emacs_env *, Lisp_Object); static enum emacs_funcall_exit module_non_local_exit_check (emacs_env *); static void check_main_thread (void); @@ -284,7 +284,7 @@ module_make_global_ref (emacs_env *env, emacs_value ref) hash_put (h, new_obj, make_natnum (1), hashcode); } - return allocate_emacs_value (env, &global_storage, new_obj); + return allocate_emacs_value (&global_storage, new_obj); } static void @@ -440,6 +440,7 @@ module_type_of (emacs_env *env, emacs_value value) { check_main_thread (); eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return); + MODULE_HANDLE_SIGNALS; return lisp_to_value (env, Ftype_of (value_to_lisp (value))); } @@ -478,6 +479,7 @@ module_make_integer (emacs_env *env, intmax_t n) { check_main_thread (); eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return); + MODULE_HANDLE_SIGNALS; if (! (MOST_NEGATIVE_FIXNUM <= n && n <= MOST_POSITIVE_FIXNUM)) { module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); @@ -850,18 +852,21 @@ module_args_out_of_range (emacs_env *env, Lisp_Object a1, Lisp_Object a2) static Lisp_Object value_to_lisp (emacs_value v) { + eassert (v != NULL); return v->v; } /* Convert an internal object to an `emacs_value'. Allocate storage - from the environment; return NULL if allocation fails. */ + from the environment; raise a signal if allocation fails. */ static emacs_value lisp_to_value (emacs_env *env, Lisp_Object o) { + eassert (env != NULL); struct emacs_env_private *p = env->private_members; + // TODO: Remove the next statement. if (p->pending_non_local_exit != emacs_funcall_exit_return) return NULL; - return allocate_emacs_value (env, &p->storage, o); + return allocate_emacs_value (&p->storage, o); } \f @@ -898,23 +903,19 @@ finalize_storage (struct emacs_value_storage *storage) } } -/* Allocate a new value from STORAGE and stores OBJ in it. Return - NULL if allocations fails and use ENV for non local exit reporting. */ +/* Allocate a new value from STORAGE and stores OBJ in it. Signal an + error if allocation fails. */ static emacs_value -allocate_emacs_value (emacs_env *env, struct emacs_value_storage *storage, +allocate_emacs_value (struct emacs_value_storage *storage, Lisp_Object obj) { - eassert (storage->current); + eassert (storage != NULL); + eassert (storage->current != NULL); eassert (storage->current->offset < value_frame_size); - eassert (! storage->current->next); + eassert (storage->current->next == NULL); if (storage->current->offset == value_frame_size - 1) { - storage->current->next = malloc (sizeof *storage->current->next); - if (! storage->current->next) - { - module_out_of_memory (env); - return NULL; - } + storage->current->next = xmalloc (sizeof *storage->current->next); initialize_frame (storage->current->next); storage->current = storage->current->next; } -- 2.6.3 ^ permalink raw reply related [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 17:27 ` Philipp Stephani @ 2015-11-22 18:50 ` Paul Eggert 2015-11-22 19:19 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-22 18:50 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel Thanks for the patch, but this handles only part of the problem, namely, the memory allocated by emacs-module.c directly. We need a way for modules themselves to allocate memory that is properly accounted for, and this allocation should be nearly as convenient as xmalloc so that modules don't need to check for failure after each allocation. Since emacs-module.c can invoke xmalloc, surely it can export a memory-allocator function implemented via xmalloc, using the same techniques emacs-module.c is already using to call xmalloc in your patch. This should work regardless of whether the module is written in C or C++. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 18:50 ` Paul Eggert @ 2015-11-22 19:19 ` Philipp Stephani 2015-11-22 19:26 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-22 19:19 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii Cc: aurelien.aptel+emacs, tzz, Daniel Colascione, Emacs developers [-- Attachment #1: Type: text/plain, Size: 717 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am So., 22. Nov. 2015 um 19:50 Uhr: > Thanks for the patch, but this handles only part of the problem, namely, > the > memory allocated by emacs-module.c directly. We need a way for modules > themselves to allocate memory that is properly accounted for, and this > allocation should be nearly as convenient as xmalloc so that modules don't > need > to check for failure after each allocation. > This is _impossible_ without using longjmp. We really don't want to allow longjmp to skip over module frames. An interface that doesn't use longjmp but returns NULL on error is fine with me. It's something entirely different though: My patch is only for the internal Emacs code. [-- Attachment #2: Type: text/html, Size: 1021 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 19:19 ` Philipp Stephani @ 2015-11-22 19:26 ` Eli Zaretskii 2015-11-22 19:58 ` Philipp Stephani 2015-11-23 2:47 ` Tom Tromey 0 siblings, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-22 19:26 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, eggert, dancol, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sun, 22 Nov 2015 19:19:49 +0000 > Cc: aurelien.aptel+emacs@gmail.com, tzz@lifelogs.com, > Emacs developers <emacs-devel@gnu.org>, Daniel Colascione <dancol@dancol.org> > > Thanks for the patch, but this handles only part of the problem, namely, > the > memory allocated by emacs-module.c directly. We need a way for modules > themselves to allocate memory that is properly accounted for, and this > allocation should be nearly as convenient as xmalloc so that modules don't > need > to check for failure after each allocation. > > This is _impossible_ without using longjmp. Why? Why cannot emacs-module.c expose an allocator, which modules will then use as a sole source of memory? And why such an allocator cannot do exactly what you did in your patch? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 19:26 ` Eli Zaretskii @ 2015-11-22 19:58 ` Philipp Stephani 2015-11-23 18:17 ` Eli Zaretskii 2015-11-23 2:47 ` Tom Tromey 1 sibling, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-22 19:58 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, eggert, dancol, emacs-devel [-- Attachment #1.1: Type: text/plain, Size: 1045 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am So., 22. Nov. 2015 um 20:26 Uhr: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Sun, 22 Nov 2015 19:19:49 +0000 > > Cc: aurelien.aptel+emacs@gmail.com, tzz@lifelogs.com, > > Emacs developers <emacs-devel@gnu.org>, Daniel Colascione < > dancol@dancol.org> > > > > Thanks for the patch, but this handles only part of the problem, > namely, > > the > > memory allocated by emacs-module.c directly. We need a way for > modules > > themselves to allocate memory that is properly accounted for, and > this > > allocation should be nearly as convenient as xmalloc so that modules > don't > > need > > to check for failure after each allocation. > > > > This is _impossible_ without using longjmp. > > Why? Why cannot emacs-module.c expose an allocator, which modules > will then use as a sole source of memory? And why such an allocator > cannot do exactly what you did in your patch? > I've attached a patch for such an allocator, but it doesn't use longjmp. [-- Attachment #1.2: Type: text/html, Size: 1746 bytes --] [-- Attachment #2: 0002-Add-functions-to-access-the-Emacs-allocator.patch --] [-- Type: application/octet-stream, Size: 2767 bytes --] From 6a39cee30848489b13ddef026a13706353145262 Mon Sep 17 00:00:00 2001 From: Philipp Stephani <phst@google.com> Date: Sun, 22 Nov 2015 20:52:55 +0100 Subject: [PATCH 2/2] Add functions to access the Emacs allocator * emacs-module.c (module_allocate_raw_memory) (module_free_raw_memory): new functions --- src/emacs-module.c | 21 +++++++++++++++++++++ src/emacs-module.h | 11 +++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/emacs-module.c b/src/emacs-module.c index 8705280..1f4e3f5 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -287,6 +287,25 @@ module_make_global_ref (emacs_env *env, emacs_value ref) return allocate_emacs_value (&global_storage, new_obj); } +static void * +module_allocate_raw_memory (emacs_env *env, ptrdiff_t size) +{ + check_main_thread (); + eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return); + MODULE_HANDLE_SIGNALS; + return xmalloc (size); +} + +static void +module_free_raw_memory (emacs_env *env, void *memory) +{ + check_main_thread (); + eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return); + MODULE_HANDLE_SIGNALS_VOID; + eassert (memory != NULL); + return xfree (memory); +} + static void module_free_global_ref (emacs_env *env, emacs_value ref) { @@ -953,6 +972,8 @@ initialize_environment (struct env_storage *env) env->pub.private_members = &env->priv; env->pub.make_global_ref = module_make_global_ref; env->pub.free_global_ref = module_free_global_ref; + env->pub.allocate_raw_memory = module_allocate_raw_memory; + env->pub.free_raw_memory = module_free_raw_memory; env->pub.non_local_exit_check = module_non_local_exit_check; env->pub.non_local_exit_clear = module_non_local_exit_clear; env->pub.non_local_exit_get = module_non_local_exit_get; diff --git a/src/emacs-module.h b/src/emacs-module.h index 06fc4c0..ecead23 100644 --- a/src/emacs-module.h +++ b/src/emacs-module.h @@ -95,6 +95,17 @@ struct emacs_env_25 void (*free_global_ref) (emacs_env *env, emacs_value global_reference); + /* Uses the Emacs memory allocator to allocate raw memory. Returns + NULL if allocation fails. Using this function over malloc(3) has + the advantage that input is correctly blocked and the memory + profiler is notified about the allocation. Memory allocated with + this function must be freed by free_raw_memory. */ + void *(*allocate_raw_memory) (emacs_env *env, ptrdiff_t size); + + /* Frees a block of memory allocated by allocate_raw_memory. The + pointer to the memory block must not be NULL. */ + void (*free_raw_memory) (emacs_env *env, void *memory); + /* Non-local exit handling. */ enum emacs_funcall_exit (*non_local_exit_check) (emacs_env *env); -- 2.6.3 ^ permalink raw reply related [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 19:58 ` Philipp Stephani @ 2015-11-23 18:17 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-23 18:17 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, eggert, dancol, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sun, 22 Nov 2015 19:58:26 +0000 > Cc: eggert@cs.ucla.edu, aurelien.aptel+emacs@gmail.com, tzz@lifelogs.com, > emacs-devel@gnu.org, dancol@dancol.org > > Why? Why cannot emacs-module.c expose an allocator, which modules > will then use as a sole source of memory? And why such an allocator > cannot do exactly what you did in your patch? > > I've attached a patch for such an allocator, but it doesn't use longjmp. Thanks. Paul, if this is OK with you, please push (Phillip doesn't have write access to the repository). ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 19:26 ` Eli Zaretskii 2015-11-22 19:58 ` Philipp Stephani @ 2015-11-23 2:47 ` Tom Tromey 2015-11-23 3:46 ` Eli Zaretskii 2015-11-23 16:29 ` Paul Eggert 1 sibling, 2 replies; 765+ messages in thread From: Tom Tromey @ 2015-11-23 2:47 UTC (permalink / raw) To: Eli Zaretskii Cc: eggert, tzz, emacs-devel, Philipp Stephani, aurelien.aptel+emacs, dancol >>>>> "Eli" == Eli Zaretskii <eliz@gnu.org> writes: Eli> Why? Why cannot emacs-module.c expose an allocator, which modules Eli> will then use as a sole source of memory? Commonly a module will use some other library, which will do whatever it does. Tom ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-23 2:47 ` Tom Tromey @ 2015-11-23 3:46 ` Eli Zaretskii 2015-11-23 16:29 ` Paul Eggert 1 sibling, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-23 3:46 UTC (permalink / raw) To: Tom Tromey Cc: eggert, tzz, emacs-devel, p.stephani2, aurelien.aptel+emacs, dancol > From: Tom Tromey <tom@tromey.com> > Cc: Philipp Stephani <p.stephani2@gmail.com>, aurelien.aptel+emacs@gmail.com, tzz@lifelogs.com, eggert@cs.ucla.edu, dancol@dancol.org, emacs-devel@gnu.org > Date: Sun, 22 Nov 2015 19:47:53 -0700 > > >>>>> "Eli" == Eli Zaretskii <eliz@gnu.org> writes: > > Eli> Why? Why cannot emacs-module.c expose an allocator, which modules > Eli> will then use as a sole source of memory? > > Commonly a module will use some other library, which will do whatever it > does. Yes, of course. The intent is to provide an allocator for Emacs-related data. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-23 2:47 ` Tom Tromey 2015-11-23 3:46 ` Eli Zaretskii @ 2015-11-23 16:29 ` Paul Eggert 2015-11-23 16:35 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Paul Eggert @ 2015-11-23 16:29 UTC (permalink / raw) To: Tom Tromey, Eli Zaretskii Cc: aurelien.aptel+emacs, Philipp Stephani, dancol, tzz, emacs-devel On 11/22/2015 06:47 PM, Tom Tromey wrote: > Commonly a module will use some other library, which will do whatever it > does. Yes, if another library calls the system malloc directly, the module author will be stuck with that behavior. However, many libraries let or require the caller to allocate memory, or provide ways for the caller to specify the memory-allocator functions, and module authors should prefer this to having the libraries invoke malloc directly, because Emacs wants to do memory accounting etc. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-23 16:29 ` Paul Eggert @ 2015-11-23 16:35 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-23 16:35 UTC (permalink / raw) To: Paul Eggert Cc: dancol, tzz, emacs-devel, p.stephani2, aurelien.aptel+emacs, tom > Cc: Philipp Stephani <p.stephani2@gmail.com>, aurelien.aptel+emacs@gmail.com, > tzz@lifelogs.com, dancol@dancol.org, emacs-devel@gnu.org > From: Paul Eggert <eggert@cs.ucla.edu> > Date: Mon, 23 Nov 2015 08:29:16 -0800 > > Yes, if another library calls the system malloc directly, the module > author will be stuck with that behavior. However, many libraries let or > require the caller to allocate memory, or provide ways for the caller to > specify the memory-allocator functions, and module authors should prefer > this to having the libraries invoke malloc directly, because Emacs wants > to do memory accounting etc. I agree. This is even more important in the Windows build of Emacs, because we provide our own implementation of malloc and friends, which should be less prone to heap fragmentation issues (it is an emulation of mmap-based malloc). ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 23:22 ` Philipp Stephani 2015-11-20 23:29 ` Paul Eggert @ 2015-11-21 8:35 ` Eli Zaretskii 2015-11-21 9:19 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-21 8:35 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Fri, 20 Nov 2015 23:22:49 +0000 > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, emacs-devel@gnu.org > > Ah, you are talking about C++ dynamic initializers! So the model is > that someone writes a module in C++, starts a thread there, and then > inside some dynamic initializer calls emacs-module interface > functions, is that it? If that's the situation, I'd suggest a > prominent commentary describing this in the source. > > The SO post talks about C++ but the issue is the same in C. AFAIK with C11 and > C++11 the execution models are harmonized. It doesn't matter for the issue at hand whether it's C, C++, Java, or whatever. My originally incorrect interpretation of what you wrote was that you are talking about initializers that are part of the module code, i.e. the emacs_module_init function they implement. > It seems the comment is overly confusing. It is supposed to warn about the > following. Naively, if you wanted to test whether you are in the main thread, > you would do (module types and naming): > > static thread_id main_thread = get_current_thread(); > bool in_main_thread() { return get_current_thread() == main_thread; } > > The dynamic initializer here is the first "get_current_thread()"; it is not > guaranteed to run in the main thread, so "main_thread" is not guaranteed to > contain the main thread ID. Therefore you have to do: > > static thread_id main_thread; // initialized later > int main() { > // guaranteed to be in the main thread > main_thread = get_current_thread(); > } > > That's all. I'm not aware of any runtime that would run dynamic initializers > outside of the main thread, but it's not impossible and easy to protect > against. AFAIK, code that does this: static thread_id main_thread = get_current_thread(); is invalid in C, because such initializers cannot call functions. So it would surprise me to see code which tried to record its thread ID before 'main'. So I think we should reword that comment to be much less mysterious and confusing than it is now. (Look how much did we need to talk about for you to explain to me what was the intent of the comment.) > Anyway, thanks for explaining this, I now know how to change the code > to DTRT on MS-Windows wrt to the thread checks. > > This is unfortunately all surprisingly subtle and vaguely defined. See e.g. > http://stackoverflow.com/q/19744250/178761 (apparently the standards are vague > about what happens to detached threads after main has exited). I don't see how that affects the issue at hand. The issue at hand is whether a thread ID of the main thread could be reused while some of the other threads belonging to the Emacs process are still running. And the answer to that on MS-Windows is AFAIU a sound NO, because as long as the Emacs process is alive, it holds a handle on the main thread, which precludes the OS from discarding that thread's kernel object. Why? because a thread handle can and is used to query the OS about that thread's conditions, like its exit code, or wait for its completion in the likes of WaitForSingleObject. So the kernel object that represents the thread must be kept by the OS as long as at least one open handle for the thread exists, and that prevents the OS from reusing the thread ID. > > See also > > http://blogs.msdn.com/b/oldnewthing/archive/2006/09/27/773741.aspx. > > We don't use IsBadWritePtr on Windows to check this, see > w32_valid_pointer_p for how this is actually implemented. > > Much of this applies generally. > > "But what should I do, then, if somebody passes me a bad pointer?" > > You should crash. Which is what we do, since eassert aborts. We will just do it sooner, which IME is a Good Thing. > Anyway, I'm surprised by this extreme POV: even if we cannot validate > a pointer 100%, surely it doesn't mean we cannot or shouldn't do some > partial job? Why this "all or nothing" approach? > > We can check whether it's NULL. Apart from that, everything else is outside of > the C standard. Emacs is not a Standard C program, far from it. It uses a lot of stuff outside of any C standard, and for a very good reason: it is a large and complicate program with many features that require access to OS facilities. IOW, using only Standard C features is not, and cannot be, a requirement for Emacs code. > We need to devise a way for it to detect that it was called from > emacs-module.c, the rest is simple, I think. > > Hmm, why does it need to detect anything? Can't it just be a different function > that doesn't signal, similar to push_handler and push_handler_nosignal? I don't think we want each of its callers call the signaling part by itself. That would be repeating the problem with malloc itself: many programs simply neglect to include the code which does TRT when it returns NULL. xmalloc solves this, and makes sure the (non-trivial) error action and message are always the same in that case. We need a variant of this for memory allocated on behalf of modules, I think. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 8:35 ` Eli Zaretskii @ 2015-11-21 9:19 ` Philipp Stephani 2015-11-21 9:33 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-21 9:19 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 6513 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am Sa., 21. Nov. 2015 um 09:35 Uhr: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Fri, 20 Nov 2015 23:22:49 +0000 > > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, > emacs-devel@gnu.org > > > > Ah, you are talking about C++ dynamic initializers! So the model is > > that someone writes a module in C++, starts a thread there, and then > > inside some dynamic initializer calls emacs-module interface > > functions, is that it? If that's the situation, I'd suggest a > > prominent commentary describing this in the source. > > > > The SO post talks about C++ but the issue is the same in C. AFAIK with > C11 and > > C++11 the execution models are harmonized. > > It doesn't matter for the issue at hand whether it's C, C++, Java, or > whatever. My originally incorrect interpretation of what you wrote > was that you are talking about initializers that are part of the > module code, i.e. the emacs_module_init function they implement. > > > It seems the comment is overly confusing. It is supposed to warn about > the > > following. Naively, if you wanted to test whether you are in the main > thread, > > you would do (module types and naming): > > > > static thread_id main_thread = get_current_thread(); > > bool in_main_thread() { return get_current_thread() == main_thread; } > > > > The dynamic initializer here is the first "get_current_thread()"; it is > not > > guaranteed to run in the main thread, so "main_thread" is not guaranteed > to > > contain the main thread ID. Therefore you have to do: > > > > static thread_id main_thread; // initialized later > > int main() { > > // guaranteed to be in the main thread > > main_thread = get_current_thread(); > > } > > > > That's all. I'm not aware of any runtime that would run dynamic > initializers > > outside of the main thread, but it's not impossible and easy to protect > > against. > > AFAIK, code that does this: > > static thread_id main_thread = get_current_thread(); > > is invalid in C, because such initializers cannot call functions. So > it would surprise me to see code which tried to record its thread ID > before 'main'. > Indeed, you're right. (Yes, I'm a C++ programmer :)) Sorry for the confusion. > > So I think we should reword that comment to be much less mysterious > and confusing than it is now. (Look how much did we need to talk > about for you to explain to me what was the intent of the comment.) > Since the alternative isn't even legal, the comment can just go away. > > > Anyway, thanks for explaining this, I now know how to change the code > > to DTRT on MS-Windows wrt to the thread checks. > > > > This is unfortunately all surprisingly subtle and vaguely defined. See > e.g. > > http://stackoverflow.com/q/19744250/178761 (apparently the standards > are vague > > about what happens to detached threads after main has exited). > > I don't see how that affects the issue at hand. The issue at hand is > whether a thread ID of the main thread could be reused while some of > the other threads belonging to the Emacs process are still running. > And the answer to that on MS-Windows is AFAIU a sound NO, because as > long as the Emacs process is alive, it holds a handle on the main > thread, which precludes the OS from discarding that thread's kernel > object. Why? because a thread handle can and is used to query the OS > about that thread's conditions, like its exit code, or wait for its > completion in the likes of WaitForSingleObject. So the kernel object > that represents the thread must be kept by the OS as long as at least > one open handle for the thread exists, and that prevents the OS from > reusing the thread ID. > Does it actually hold that handle? It sounds reasonable, but I can't find it documented. > > > > See also > > > http://blogs.msdn.com/b/oldnewthing/archive/2006/09/27/773741.aspx > . > > > > We don't use IsBadWritePtr on Windows to check this, see > > w32_valid_pointer_p for how this is actually implemented. > > > > Much of this applies generally. > > > "But what should I do, then, if somebody passes me a bad pointer?" > > > You should crash. > > Which is what we do, since eassert aborts. We will just do it sooner, > which IME is a Good Thing. > OK. We should be a bit careful with the current implementation of valid_pointer_p though, as AFAIK write(2) could cast the pointer it receives to char* and dereference it, but that's probably no worse than not checking it at all, and unrelated to modules. > > > Anyway, I'm surprised by this extreme POV: even if we cannot validate > > a pointer 100%, surely it doesn't mean we cannot or shouldn't do some > > partial job? Why this "all or nothing" approach? > > > > We can check whether it's NULL. Apart from that, everything else is > outside of > > the C standard. > > Emacs is not a Standard C program, far from it. It uses a lot of > stuff outside of any C standard, and for a very good reason: it is a > large and complicate program with many features that require access to > OS facilities. > > IOW, using only Standard C features is not, and cannot be, a > requirement for Emacs code. > Fair enough. > > > We need to devise a way for it to detect that it was called from > > emacs-module.c, the rest is simple, I think. > > > > Hmm, why does it need to detect anything? Can't it just be a different > function > > that doesn't signal, similar to push_handler and push_handler_nosignal? > > I don't think we want each of its callers call the signaling part by > itself. That would be repeating the problem with malloc itself: many > programs simply neglect to include the code which does TRT when it > returns NULL. xmalloc solves this, and makes sure the (non-trivial) > error action and message are always the same in that case. > > We need a variant of this for memory allocated on behalf of modules, I > think. > But this would require modules to be prepared for handling longjmps, which in general they aren't. In an "unsafe" language like C, we can't do without the users' cooperation. If users ignore NULL returns from malloc, that's a bug and we can't do much about it. We could make it harder to accidentially ignore the result: bool emacs_malloc(size_t size, void **out) __attribute__((warn_unused_result)); but that requires a compiler extension and is not really consistent with the rest of the module interface, where NULL is regularly returned on failure. [-- Attachment #2: Type: text/html, Size: 8752 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 9:19 ` Philipp Stephani @ 2015-11-21 9:33 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-21 9:33 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sat, 21 Nov 2015 09:19:48 +0000 > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, emacs-devel@gnu.org > > > Anyway, thanks for explaining this, I now know how to change the code > > to DTRT on MS-Windows wrt to the thread checks. > > > > This is unfortunately all surprisingly subtle and vaguely defined. See > e.g. > > http://stackoverflow.com/q/19744250/178761 (apparently the standards are > vague > > about what happens to detached threads after main has exited). > > I don't see how that affects the issue at hand. The issue at hand is > whether a thread ID of the main thread could be reused while some of > the other threads belonging to the Emacs process are still running. > And the answer to that on MS-Windows is AFAIU a sound NO, because as > long as the Emacs process is alive, it holds a handle on the main > thread, which precludes the OS from discarding that thread's kernel > object. Why? because a thread handle can and is used to query the OS > about that thread's conditions, like its exit code, or wait for its > completion in the likes of WaitForSingleObject. So the kernel object > that represents the thread must be kept by the OS as long as at least > one open handle for the thread exists, and that prevents the OS from > reusing the thread ID. > > Does it actually hold that handle? It sounds reasonable, but I can't find it > documented. Not sure I understand what you are saying. We create a handle, and then never close it. So it stays open for as long as the process lives. If some of the process's threads are still running, the process is still alive, so the handle is not closed by the OS. > I don't think we want each of its callers call the signaling part by > itself. That would be repeating the problem with malloc itself: many > programs simply neglect to include the code which does TRT when it > returns NULL. xmalloc solves this, and makes sure the (non-trivial) > error action and message are always the same in that case. > > We need a variant of this for memory allocated on behalf of modules, I > think. > > But this would require modules to be prepared for handling longjmps, which in > general they aren't. The jump should be in a module-friendly way, obviously. IOW, it will have to call (the moral equivalent of) module_non_local_exit_signal. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 9:53 ` Eli Zaretskii ` (2 preceding siblings ...) 2015-11-20 19:58 ` Philipp Stephani @ 2015-11-21 9:01 ` Philipp Stephani 2015-11-21 9:29 ` Eli Zaretskii 3 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-21 9:01 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 2482 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am Fr., 20. Nov. 2015 um 10:54 Uhr: > > > Re this fragment from module.c: > > > > Lisp_Object ret = list4 (Qlambda, > > list2 (Qand_rest, Qargs), > > documentation ? build_string (documentation) : Qnil, > > list3 (module_call_func, > > envobj, > > Qargs)); > > > > Thou shalt not use build_string, except when you _know_ the argument > > will always be a pure-ASCII string. Practically, this means the > > argument must be a constant ASCII string. See these messages (and the > > preceding discussion, if you are interested) for the gory details: > > > > > http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00955.html > > > http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00976.html > > > http://lists.gnu.org/archive/html/bug-gnu-emacs/2013-10/msg00979.html > > > > The above should call make_multibyte_string instead. > > > > > > We had a discussion about encodings in > > https://github.com/aaptel/emacs-dynamic-module/issues/37. Sorry that > this > > didn't get resolved earlier; it's an important point. My suggestion > would be to > > always mandate specifying an encoding whenever a char* is passed, and > limit > > that to two or three functions dealing with creating strings and > accessing > > string contents. Would that address your concerns? > > No, this is not about encoding at all. This is about calling > build_string: you should only call it when the argument is a fixed > ASCII string. If the argument is not fixed or might include non-ASCII > characters, you should call make_multibyte_string instead. That's > because build_string might decide on its own whether to produce a > unibyte or a multibyte string, out of your control, whereas we always > want a multibyte string in this context. > > build_string doesn't encode or decode its argument, it creates a Lisp > object whose text is taken from the argument. It's similar to > make_number in that respect. > > Let me summarize the issues I see: The internal Emacs encoding can change between versions (command in mule-conf.el), therefore we shouldn't use it in the module API. IIUC this rules out make_multibyte_string: it only accepts the internal encoding. Therefore I proposed to always have users specify the encoding explicitly and then use code_convert_string_norecord to create the Lisp string objects. Would that work? (We probably then need another set of functions for unibyte strings.) [-- Attachment #2: Type: text/html, Size: 3478 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 9:01 ` Philipp Stephani @ 2015-11-21 9:29 ` Eli Zaretskii 2015-11-21 10:31 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-21 9:29 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sat, 21 Nov 2015 09:01:12 +0000 > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, emacs-devel@gnu.org > > Let me summarize the issues I see: The internal Emacs encoding can change > between versions (command in mule-conf.el), therefore we shouldn't use it in > the module API. IIUC this rules out make_multibyte_string: it only accepts the > internal encoding. Therefore I proposed to always have users specify the > encoding explicitly and then use code_convert_string_norecord to create the > Lisp string objects. Would that work? (We probably then need another set of > functions for unibyte strings.) I'm not sure I'm following, so let's take a step back, okay? My comments were about using build_string and make_string in 2 functions defined in emacs-module.c: module_make_function and module_make_string. Both of these emacs-module.c functions produce strings for consumption by Emacs, AFAIU: the former produces a doc string of a function defined by a module, which will be used by various documentation-related functions and commands within Emacs, the latter produces a string to be passed to Emacs Lisp code for use as any other Lisp string. Do you agree so far? If you agree, then in both cases the strings these functions return should be in the internal representation of strings used by Emacs, not in some encoding like UTF-8 or ISO-8859-1. (We could also use encoded strings, but that would require Lisp programs using module functions to always decode any strings they receive, which is less efficient and more error-prone.) (Btw, I don't think we should worry about changing the internal representation of characters in Emacs, because make_multibyte_string will be updated as needed.) This is what my comments were about. I think that you, by contrast, are talking about the encoding of the _input_ strings, in this case the 'documentation' argument to module_make_function and 'str' argument to module_make_string. My assumption was that these arguments will always have to be in UTF-8 encoding; if that assumption is true, then no decoding via code_convert_string_norecord is necessary, since make_multibyte_string will DTRT. We can (and probably should) document the fact that all non-ASCII strings must be UTF-8 encoded as a requirement of the emacs-module interface. If you are thinking about accepting strings encoded in other encodings, I'd consider this an extension, to be added later if needed. After all, a module can easily convert to UTF-8 by itself, using facilities such as iconv. In any case, code_convert_string_norecord cannot be the complete solution, because it accepts Lisp string objects, not C strings. You still need to create a Lisp string (but this time using make_unibyte_string). The point is to always use either make_unibyte_string or make_multibyte_string, and never build_string or make_string; the latter 2 should only be used for fixed ASCII-only strings. I hope this clarifies the issue. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 9:29 ` Eli Zaretskii @ 2015-11-21 10:31 ` Philipp Stephani 2015-11-21 10:45 ` David Kastrup 2015-11-21 11:10 ` Eli Zaretskii 0 siblings, 2 replies; 765+ messages in thread From: Philipp Stephani @ 2015-11-21 10:31 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 4165 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am Sa., 21. Nov. 2015 um 10:30 Uhr: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Sat, 21 Nov 2015 09:01:12 +0000 > > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, > emacs-devel@gnu.org > > > > Let me summarize the issues I see: The internal Emacs encoding can change > > between versions (command in mule-conf.el), therefore we shouldn't use > it in > > the module API. IIUC this rules out make_multibyte_string: it only > accepts the > > internal encoding. Therefore I proposed to always have users specify the > > encoding explicitly and then use code_convert_string_norecord to create > the > > Lisp string objects. Would that work? (We probably then need another set > of > > functions for unibyte strings.) > > I'm not sure I'm following, so let's take a step back, okay? > > My comments were about using build_string and make_string in 2 > functions defined in emacs-module.c: module_make_function and > module_make_string. Both of these emacs-module.c functions produce > strings for consumption by Emacs, AFAIU: the former produces a doc > string of a function defined by a module, which will be used by > various documentation-related functions and commands within Emacs, the > latter produces a string to be passed to Emacs Lisp code for use as > any other Lisp string. Do you agree so far? > Yes. > > If you agree, then in both cases the strings these functions return > should be in the internal representation of strings used by Emacs, not > in some encoding like UTF-8 or ISO-8859-1. (We could also use encoded > strings, but that would require Lisp programs using module functions > to always decode any strings they receive, which is less efficient and > more error-prone.) > Yes. Just for understanding: there are two types of strings: unibyte (just a sequence of chars), and multibyte (sequence of chars interpreted in the internal Emacs encoding), right? > > (Btw, I don't think we should worry about changing the internal > representation of characters in Emacs, because make_multibyte_string > will be updated as needed.) > This is a crucial point. If the internal encoding never changes, then we can declare that those string parameters are expected to be in the internal encoding. But see the discussion in https://github.com/aaptel/emacs-dynamic-module/issues/37: the comment in mule-conf.el seems to indicate that the internal encoding is not stable. > > This is what my comments were about. I think that you, by contrast, > are talking about the encoding of the _input_ strings, in this case > the 'documentation' argument to module_make_function and 'str' > argument to module_make_string. My assumption was that these > arguments will always have to be in UTF-8 encoding; if that assumption > is true, then no decoding via code_convert_string_norecord is > necessary, since make_multibyte_string will DTRT. We can (and > probably should) document the fact that all non-ASCII strings must be > UTF-8 encoded as a requirement of the emacs-module interface. > Or rather, an extension to UTF-8 capable of encoding surrogate code points and numbers that are not code points, as described in https://www.gnu.org/software/emacs/manual/html_node/elisp/Text-Representations.html . > > If you are thinking about accepting strings encoded in other > encodings, I'd consider this an extension, to be added later if > needed. After all, a module can easily convert to UTF-8 by itself, > using facilities such as iconv. > Yes, provided the internal Emacs encoding is stable. > > In any case, code_convert_string_norecord cannot be the complete > solution, because it accepts Lisp string objects, not C strings. You > still need to create a Lisp string (but this time using > make_unibyte_string). The point is to always use either > make_unibyte_string or make_multibyte_string, and never build_string > or make_string; the latter 2 should only be used for fixed ASCII-only > strings. > > Yes, that's fine, the question is about whether the internal encoding is stable. If it's stable, we can use make_multibyte_string; if not, we can only use make_unibyte_string. [-- Attachment #2: Type: text/html, Size: 5844 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 10:31 ` Philipp Stephani @ 2015-11-21 10:45 ` David Kastrup 2015-11-21 11:10 ` Eli Zaretskii 1 sibling, 0 replies; 765+ messages in thread From: David Kastrup @ 2015-11-21 10:45 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, Eli Zaretskii, tzz, emacs-devel Philipp Stephani <p.stephani2@gmail.com> writes: > Eli Zaretskii <eliz@gnu.org> schrieb am Sa., 21. Nov. 2015 um 10:30 Uhr: > >> This is what my comments were about. I think that you, by contrast, >> are talking about the encoding of the _input_ strings, in this case >> the 'documentation' argument to module_make_function and 'str' >> argument to module_make_string. My assumption was that these >> arguments will always have to be in UTF-8 encoding; if that >> assumption is true, then no decoding via code_convert_string_norecord >> is necessary, since make_multibyte_string will DTRT. We can (and >> probably should) document the fact that all non-ASCII strings must be >> UTF-8 encoded as a requirement of the emacs-module interface. >> > > Or rather, an extension to UTF-8 capable of encoding surrogate code > points and numbers that are not code points, as described in > https://www.gnu.org/software/emacs/manual/html_node/elisp/Text-Representations.html > . That's mostly irrelevant for fixed strings as valid UTF-8 is encoded as itself and invalid UTF-8 is encoded as well-processable invalid UTF-8. Apart from strings generated with `string-as-multibyte' (what kind of terrible idea is that?) or unibyte strings, all Emacs strings are well-processable (meaning that they are represented by start byte and extension bytes, with the start byte encoding the byte count 1-6 in the UTF-8 typical manner even if UTF-8 itself does not go beyond the Unicode range encodable in 4 bytes). > Yes, provided the internal Emacs encoding is stable. It has changed several times in the past. It's a reasonably good bet that the basics of its current UTF-8 scheme will stick around. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 10:31 ` Philipp Stephani 2015-11-21 10:45 ` David Kastrup @ 2015-11-21 11:10 ` Eli Zaretskii 2015-11-21 12:11 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-21 11:10 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sat, 21 Nov 2015 10:31:24 +0000 > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, emacs-devel@gnu.org > > If you agree, then in both cases the strings these functions return > should be in the internal representation of strings used by Emacs, not > in some encoding like UTF-8 or ISO-8859-1. (We could also use encoded > strings, but that would require Lisp programs using module functions > to always decode any strings they receive, which is less efficient and > more error-prone.) > > Yes. Just for understanding: there are two types of strings: unibyte (just a > sequence of chars), and multibyte (sequence of chars interpreted in the > internal Emacs encoding), right? Yes. However, unibyte strings are just streams of bytes; Emacs cannot interpret them, and they generally appear on display as octal escapes. They should never be presented to the user, except if the user explicitly requested that, e.g. by a command such as find-file-literally. > (Btw, I don't think we should worry about changing the internal > representation of characters in Emacs, because make_multibyte_string > will be updated as needed.) > > This is a crucial point. If the internal encoding never changes, then we can > declare that those string parameters are expected to be in the internal > encoding. No, we cannot, or rather should not. It is unreasonable to expect external modules to know the intricacies of the internal representation. Most Emacs hackers don't. > But see the discussion in > https://github.com/aaptel/emacs-dynamic-module/issues/37: the comment in > mule-conf.el seems to indicate that the internal encoding is not stable. That discussion is about zero-copy access to Emacs buffer text and Emacs strings inside module code. Such access is indeed impossible without either knowing _something_ about the internal representation, or having additional APIs in emacs-module.c that allow modules such access while hiding the details of the internal representation. We could discuss extending the module functionality to include this. But that is a separate issue from what module_make_function and module_make_string do. These two functions are basic, and don't need to know about the internal representation or use it. While direct access to Emacs buffer text will be needed by only some modules, module_make_function will be used by all of them, and module_make_string by many. So I think we shouldn't conflate these two issues; they are separate. > This is what my comments were about. I think that you, by contrast, > are talking about the encoding of the _input_ strings, in this case > the 'documentation' argument to module_make_function and 'str' > argument to module_make_string. My assumption was that these > arguments will always have to be in UTF-8 encoding; if that assumption > is true, then no decoding via code_convert_string_norecord is > necessary, since make_multibyte_string will DTRT. We can (and > probably should) document the fact that all non-ASCII strings must be > UTF-8 encoded as a requirement of the emacs-module interface. > > Or rather, an extension to UTF-8 capable of encoding surrogate code points and > numbers that are not code points, as described in > https://www.gnu.org/software/emacs/manual/html_node/elisp/Text-Representations.html. No, I meant strict UTF-8, not its Emacs extension. > If you are thinking about accepting strings encoded in other > encodings, I'd consider this an extension, to be added later if > needed. After all, a module can easily convert to UTF-8 by itself, > using facilities such as iconv. > > Yes, provided the internal Emacs encoding is stable. That's not what I meant. (AFAIK, iconv doesn't know about the Emacs internal representation.) I meant that a module could convert from any encoding to UTF-8, and then pass the resulting UTF-8 string to the emacs-module API. > In any case, code_convert_string_norecord cannot be the complete > solution, because it accepts Lisp string objects, not C strings. You > still need to create a Lisp string (but this time using > make_unibyte_string). The point is to always use either > make_unibyte_string or make_multibyte_string, and never build_string > or make_string; the latter 2 should only be used for fixed ASCII-only > strings. > > Yes, that's fine, the question is about whether the internal encoding is > stable. With my suggestion, the stability of the internal representation is not an issue. > If it's stable, we can use make_multibyte_string; if not, we can > only use make_unibyte_string. If the arguments strings are in strict UTF-8, then make_multibyte_string will DTRT automagically, no matter what the internal representation is. That is their contract. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 11:10 ` Eli Zaretskii @ 2015-11-21 12:11 ` Philipp Stephani 2015-11-21 13:23 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-21 12:11 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 4102 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am Sa., 21. Nov. 2015 um 12:10 Uhr: > > (Btw, I don't think we should worry about changing the internal > > representation of characters in Emacs, because make_multibyte_string > > will be updated as needed.) > > > > This is a crucial point. If the internal encoding never changes, then we > can > > declare that those string parameters are expected to be in the internal > > encoding. > > No, we cannot, or rather should not. It is unreasonable to expect > external modules to know the intricacies of the internal > representation. Most Emacs hackers don't. > Fine with me, but how would we then represent Emacs strings that are not valid Unicode strings? Just raise an error? > > > But see the discussion in > > https://github.com/aaptel/emacs-dynamic-module/issues/37: the comment in > > mule-conf.el seems to indicate that the internal encoding is not stable. > > That discussion is about zero-copy access to Emacs buffer text and > Emacs strings inside module code. Partially, the encoding discussion is also part of that because it's required to specify the encoding before zero-copy access is even possible. > Such access is indeed impossible > without either knowing _something_ about the internal representation, > or having additional APIs in emacs-module.c that allow modules such > access while hiding the details of the internal representation. We > could discuss extending the module functionality to include this. > > Yes, there's no need for that in this subthread though. > But that is a separate issue from what module_make_function and > module_make_string do. These two functions are basic, and don't need > to know about the internal representation or use it. While direct > access to Emacs buffer text will be needed by only some modules, > module_make_function will be used by all of them, and > module_make_string by many. > > So I think we shouldn't conflate these two issues; they are separate. > OK. > > > This is what my comments were about. I think that you, by contrast, > > are talking about the encoding of the _input_ strings, in this case > > the 'documentation' argument to module_make_function and 'str' > > argument to module_make_string. My assumption was that these > > arguments will always have to be in UTF-8 encoding; if that > assumption > > is true, then no decoding via code_convert_string_norecord is > > necessary, since make_multibyte_string will DTRT. We can (and > > probably should) document the fact that all non-ASCII strings must be > > UTF-8 encoded as a requirement of the emacs-module interface. > > > > Or rather, an extension to UTF-8 capable of encoding surrogate code > points and > > numbers that are not code points, as described in > > > https://www.gnu.org/software/emacs/manual/html_node/elisp/Text-Representations.html > . > > No, I meant strict UTF-8, not its Emacs extension. > That would be possible and provide a clean interface. However, Emacs strings are extended, so we'd need to specify how they interact with UTF-8 strings. - If a module passes a char sequence that's not a valid UTF-8 string, but a valid Emacs multibyte string, what should happen? Error, undefined behavior, silently accepted? - If copy_string_contents is passed an Emacs string that is not a valid Unicode string, what should happen? Error, or should the internal representation be silently leaked? > > If it's stable, we can use make_multibyte_string; if not, we can > > only use make_unibyte_string. > > If the arguments strings are in strict UTF-8, then > make_multibyte_string will DTRT automagically, no matter what the > internal representation is. That is their contract. > OK, then we can use that, of course. The question of handling invalid UTF-8 strings is still open, though, as make_multibyte_string doesn't enforce valid UTF-8. If it's the contract of make_multibyte_string that it will always accept UTF-8, then that should be added as a comment to that function. Currently I don't see it documented anywhere. [-- Attachment #2: Type: text/html, Size: 5697 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 12:11 ` Philipp Stephani @ 2015-11-21 13:23 ` Eli Zaretskii 2015-11-22 9:25 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-21 13:23 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sat, 21 Nov 2015 12:11:45 +0000 > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, emacs-devel@gnu.org > > No, we cannot, or rather should not. It is unreasonable to expect > external modules to know the intricacies of the internal > representation. Most Emacs hackers don't. > > Fine with me, but how would we then represent Emacs strings that are not valid > Unicode strings? Just raise an error? No need to raise an error. Strings that are returned to modules should be encoded into UTF-8. That encoding already takes care of these situations: it either produces the UTF-8 encoding of the equivalent Unicode characters, or outputs raw bytes. We are using this all the time when we save files or send stuff over the network. > No, I meant strict UTF-8, not its Emacs extension. > > That would be possible and provide a clean interface. However, Emacs strings > are extended, so we'd need to specify how they interact with UTF-8 strings. > > * If a module passes a char sequence that's not a valid UTF-8 string, but a > valid Emacs multibyte string, what should happen? Error, undefined behavior, > silently accepted? We are quite capable of quietly accepting such strings, so that is what I would suggest. Doing so would be in line with what Emacs does when such invalid sequences come from other sources, like files. > * If copy_string_contents is passed an Emacs string that is not a valid Unicode > string, what should happen? How can that happen? The Emacs string comes from the Emacs bowels, so it must be "valid" string by Emacs standards. Or maybe I don't understand what you mean by "invalid Unicode string". In any case, we already deal with any such problems when we save a buffer to a file, or send it over the network. This isn't some new problem we need to cope with. > OK, then we can use that, of course. The question of handling invalid UTF-8 > strings is still open, though, as make_multibyte_string doesn't enforce valid > UTF-8. It doesn't enforce valid UTF-8 because it can handle invalid UTF-8 as well. That's by design. > If it's the contract of make_multibyte_string that it will always accept UTF-8, > then that should be added as a comment to that function. Currently I don't see > it documented anywhere. That part of the documentation is only revealed to veteran Emacs hackers, subject to swearing not to reveal that to the uninitiated and to some blood-letting that seals the oath ;-) ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 13:23 ` Eli Zaretskii @ 2015-11-22 9:25 ` Philipp Stephani 2015-11-22 14:56 ` Philipp Stephani 2015-11-22 17:35 ` Eli Zaretskii 0 siblings, 2 replies; 765+ messages in thread From: Philipp Stephani @ 2015-11-22 9:25 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 3718 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am Sa., 21. Nov. 2015 um 14:23 Uhr: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Sat, 21 Nov 2015 12:11:45 +0000 > > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, > emacs-devel@gnu.org > > > > No, we cannot, or rather should not. It is unreasonable to expect > > external modules to know the intricacies of the internal > > representation. Most Emacs hackers don't. > > > > Fine with me, but how would we then represent Emacs strings that are not > valid > > Unicode strings? Just raise an error? > > No need to raise an error. Strings that are returned to modules > should be encoded into UTF-8. That encoding already takes care of > these situations: it either produces the UTF-8 encoding of the > equivalent Unicode characters, or outputs raw bytes. > Then we should document such a situation and give module authors a way to detect them. For example, what happens if a sequence of such raw bytes happens to be a valid UTF-8 sequence? Is there a way for module code to detect this situation? > > We are using this all the time when we save files or send stuff over > the network. > > > No, I meant strict UTF-8, not its Emacs extension. > > > > That would be possible and provide a clean interface. However, Emacs > strings > > are extended, so we'd need to specify how they interact with UTF-8 > strings. > > > > * If a module passes a char sequence that's not a valid UTF-8 string, > but a > > valid Emacs multibyte string, what should happen? Error, undefined > behavior, > > silently accepted? > > We are quite capable of quietly accepting such strings, so that is > what I would suggest. Doing so would be in line with what Emacs does > when such invalid sequences come from other sources, like files. > If we accept such strings, then we should document what the extensions are. - Are UTF-8-like sequences encoding surrogate code points accepted? - Are UTF-8-like sequences encoding integers outside the Unicode codespace accepted? - Are non-shortest forms accepted? - Are other invalid code unit sequences accepted? If the answer to any of these is "yes", we can't say we accept UTF-8, because we don't. Rather we should say what is actually accepted. > > > * If copy_string_contents is passed an Emacs string that is not a valid > Unicode > > string, what should happen? > > How can that happen? The Emacs string comes from the Emacs bowels, so > it must be "valid" string by Emacs standards. Or maybe I don't > understand what you mean by "invalid Unicode string". > A sequence of integers where at least one element is not a Unicode scalar value. > > In any case, we already deal with any such problems when we save a > buffer to a file, or send it over the network. This isn't some new > problem we need to cope with. > Yes, but the module interface is new, it doesn't necessarily have to have the same behavior. If we say we emit only UTF-8, then we should do so. > > > OK, then we can use that, of course. The question of handling invalid > UTF-8 > > strings is still open, though, as make_multibyte_string doesn't enforce > valid > > UTF-8. > > It doesn't enforce valid UTF-8 because it can handle invalid UTF-8 as > well. That's by design. > Then whatever it handles needs to be specified. > > > If it's the contract of make_multibyte_string that it will always accept > UTF-8, > > then that should be added as a comment to that function. Currently I > don't see > > it documented anywhere. > > That part of the documentation is only revealed to veteran Emacs > hackers, subject to swearing not to reveal that to the uninitiated and > to some blood-letting that seals the oath ;-) > I see ;-) [-- Attachment #2: Type: text/html, Size: 5362 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 9:25 ` Philipp Stephani @ 2015-11-22 14:56 ` Philipp Stephani 2015-11-22 18:04 ` Eli Zaretskii 2015-11-22 17:35 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-22 14:56 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 3031 bytes --] Philipp Stephani <p.stephani2@gmail.com> schrieb am So., 22. Nov. 2015 um 10:25 Uhr: > Eli Zaretskii <eliz@gnu.org> schrieb am Sa., 21. Nov. 2015 um 14:23 Uhr: > >> > From: Philipp Stephani <p.stephani2@gmail.com> >> > Date: Sat, 21 Nov 2015 12:11:45 +0000 >> > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, >> emacs-devel@gnu.org >> > >> > No, we cannot, or rather should not. It is unreasonable to expect >> > external modules to know the intricacies of the internal >> > representation. Most Emacs hackers don't. >> > >> > Fine with me, but how would we then represent Emacs strings that are >> not valid >> > Unicode strings? Just raise an error? >> >> No need to raise an error. Strings that are returned to modules >> should be encoded into UTF-8. That encoding already takes care of >> these situations: it either produces the UTF-8 encoding of the >> equivalent Unicode characters, or outputs raw bytes. >> > > Then we should document such a situation and give module authors a way to > detect them. For example, what happens if a sequence of such raw bytes > happens to be a valid UTF-8 sequence? Is there a way for module code to > detect this situation? > > I've thought a bit more about this issue an in the following I'll attempt to derive the desired behavior from first principles without referring to internal Emacs functions. There are two kinds of Emacs strings, unibyte and multibyte. https://www.gnu.org/software/emacs/manual/html_node/elisp/Text-Representations.html and https://www.gnu.org/software/emacs/manual/html_node/elisp/Character-Codes.html agree that multibyte strings are sequences of integers (let's avoid the overloaded and vague term "characters") in the range 0 to #x3FFFFF (inclusive). It is also clear that within the subset of that range corresponding the the Unicode codespace the intergers are interpreted as Unicode code points. Given that new APIs should use UTF-8, the following approach looks reasonable to me: - There are two sets of functions for creating and reading strings, unibyte and multibyte. If a string of the wrong type is passed, a signal is raised. This way the two types are clearly separated. - The behavior of the unibyte API is uncontroversial and has no failure modes apart from generic ones such as wrong type, argument out of range, OOM. - The multibyte API should use an extension of UTF-8 to encode Emacs strings. The extension is the obvious one already in use in multiple places. - There should be a one-to-one mapping between Emacs multibyte strings and encoded module API strings. Therefore non-shortest forms, illegal code unit sequences, and code unit sequences that would encode values outside the range of Emacs characters are illegal and raise a signal. Likewise, such sequences will never be returned from Emacs. I think this is a relatively simple and unsurprising approach. It allows encoding the documented Emacs character space while still being fully compatible with UTF-8 and not resorting to undocumented Emacs internals. [-- Attachment #2: Type: text/html, Size: 4258 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 14:56 ` Philipp Stephani @ 2015-11-22 18:04 ` Eli Zaretskii 2015-11-22 19:10 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-22 18:04 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sun, 22 Nov 2015 14:56:12 +0000 > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, emacs-devel@gnu.org > > - The multibyte API should use an extension of UTF-8 to encode Emacs strings. > The extension is the obvious one already in use in multiple places. It is only used in one place: the internal representation of characters in buffers and strings. Emacs _never_ lets this internal representation leak outside. In practice the last sentence means that text that Emacs encoded in UTF-8 will only include either valid UTF-8 sequences of characters whose codepoints are below #x200000 or single bytes that don't belong to any UTF-8 sequence. You are suggesting to expose the internal representation to outside application code, which predictably will cause that representation to leak into Lisp. That'd be a disaster. We had something like that back in the Emacs 20 era, and it took many years to plug those leaks. We would be making a grave mistake to go back there. What you suggest is also impossible without deep changes in how we decode and encode text: that process maps codepoints above #1FFFFF to either codepoints below that mark or to raw bytes. So it's impossible to produce these high codes in UTF-8 compatible form while handling UTF-8 text. To say nothing about the simple fact that no library function in any C library will ever be able to do anything useful with such codepoints, because they are our own invention. > - There should be a one-to-one mapping between Emacs multibyte strings and > encoded module API strings. UTF-8 encoded strings satisfy that requirement. > Therefore non-shortest forms, illegal code unit sequences, and code > unit sequences that would encode values outside the range of Emacs > characters are illegal and raise a signal. Once again, this was tried in the past and was found to be a bad idea. Emacs provides features to test the result of converting invalid sequences, for the purposes of detecting such problems, but it leaves that to the application. > Likewise, such sequences will never be returned from Emacs. Emacs doesn't return invalid sequences, if the original text didn't include raw bytes. If there were raw bytes in the original text, Emacs has no choice but return them back, or else it will violate a basic expectation from a text-processing program: that it shall never change the portions of text that were not affected by the processing. > I think this is a relatively simple and unsurprising approach. It allows > encoding the documented Emacs character space while still being fully > compatible with UTF-8 and not resorting to undocumented Emacs internals. So does the approach I suggested. The advantage of my suggestion is that it follows a long Emacs tradition about every aspect of encoding and decoding text, and doesn't require any changes in the existing infrastructure. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 18:04 ` Eli Zaretskii @ 2015-11-22 19:10 ` Philipp Stephani 2015-11-22 19:43 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-22 19:10 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 5637 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am So., 22. Nov. 2015 um 19:04 Uhr: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Sun, 22 Nov 2015 14:56:12 +0000 > > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, > emacs-devel@gnu.org > > > > - The multibyte API should use an extension of UTF-8 to encode Emacs > strings. > > The extension is the obvious one already in use in multiple places. > > It is only used in one place: the internal representation of > characters in buffers and strings. Emacs _never_ lets this internal > representation leak outside. If I run in scratch: (with-temp-buffer (insert #x3fff40) (describe-char (point-min))) Then the resulting help buffer says "buffer code: #xF8 #x8F #xBF #xBD #x80", is that not considered a leak? > In practice the last sentence means that > text that Emacs encoded in UTF-8 will only include either valid UTF-8 > sequences of characters whose codepoints are below #x200000 or single > bytes that don't belong to any UTF-8 sequence. > I get the same result as above when running (with-temp-buffer (call-process "echo" nil t nil (string #x3fff40)) (describe-char (point-min))) that means the non-UTF sequence is even "leaked" to the external process! > > You are suggesting to expose the internal representation to outside > application code, which predictably will cause that representation to > leak into Lisp. That'd be a disaster. We had something like that > back in the Emacs 20 era, and it took many years to plug those leaks. > We would be making a grave mistake to go back there. > I don't suggest leaking anything what isn't already leaked. The extension of the codespace to 22 bits is well documented. > > What you suggest is also impossible without deep changes in how we > decode and encode text: that process maps codepoints above #1FFFFF to > either codepoints below that mark or to raw bytes. So it's impossible > to produce these high codes in UTF-8 compatible form while handling > UTF-8 text. To say nothing about the simple fact that no library > function in any C library will ever be able to do anything useful with > such codepoints, because they are our own invention. > Unless the behavior changed recently, that doesn't seem the case: (encode-coding-string (string #x3fff40) 'utf-8-unix) "\370\217\277\275\200" Or are you talking about something different? > > > - There should be a one-to-one mapping between Emacs multibyte strings > and > > encoded module API strings. > > UTF-8 encoded strings satisfy that requirement. > No! UTF-8 can only encode Unicode scalar values. Only the Emacs extension to UTF-8 (which I think Emacs calls "UTF-8" unfortunately) satisfies this. If you are talking about this extension, then we talk about the same thing anyway. > > > Therefore non-shortest forms, illegal code unit sequences, and code > > unit sequences that would encode values outside the range of Emacs > > characters are illegal and raise a signal. > > Once again, this was tried in the past and was found to be a bad idea. > Emacs provides features to test the result of converting invalid > sequences, for the purposes of detecting such problems, but it leaves > that to the application. > It's probably OK to accept invalid sequences for consistency with decode-coding-string and friends. I don't really like it though: the module API, like decode-coding-string, is not a general-purpose UI for end users, and accepting invalid sequences is error-prone and can even introduce security issues (see e.g. https://blogs.oracle.com/CoreJavaTechTips/entry/the_overhaul_of_java_utf). > > > Likewise, such sequences will never be returned from Emacs. > > Emacs doesn't return invalid sequences, if the original text didn't > include raw bytes. If there were raw bytes in the original text, > Emacs has no choice but return them back, or else it will violate a > basic expectation from a text-processing program: that it shall never > change the portions of text that were not affected by the processing. > It seems that Emacs does return invalid sequences for characters such as #x3ffff40 (or anything else outside of Unicode except the 127 values for encoding raw bytes). Returning raw bytes means that encoding and decoding isn't a perfect roundtrip: (decode-coding-string (encode-coding-string (string #x3fffc2 #x3fffbb) 'utf-8-unix) 'utf-8-unix) "»" We might be able to live with that as it's an extreme edge case. > > > I think this is a relatively simple and unsurprising approach. It allows > > encoding the documented Emacs character space while still being fully > > compatible with UTF-8 and not resorting to undocumented Emacs internals. > > So does the approach I suggested. The advantage of my suggestion is > that it follows a long Emacs tradition about every aspect of encoding > and decoding text, and doesn't require any changes in the existing > infrastructure. > What are the exact difference between the approaches? As far as I can see differences exist only for the following points: - Accepting invalid sequences. I consider that a bug in general-purpose APIs, including decode-coding-string. However, given that Emacs already extends the Unicode codespace and therefore has to accept some invalid sequences anyway, it might be OK if it's clearly documented. - Emitting raw bytes instead of extended sequences. Though I'm not a fan of this it might be unavoidable to be able to treat strings transparently (which is desirable). [-- Attachment #2: Type: text/html, Size: 7815 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 19:10 ` Philipp Stephani @ 2015-11-22 19:43 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-22 19:43 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sun, 22 Nov 2015 19:10:44 +0000 > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, emacs-devel@gnu.org > > It is only used in one place: the internal representation of > characters in buffers and strings. Emacs _never_ lets this internal > representation leak outside. > > If I run in scratch: > > (with-temp-buffer > (insert #x3fff40) > (describe-char (point-min))) Emacs will never find such "byte" in any text. So this feature is not really relevant to the issue at hand. > Then the resulting help buffer says "buffer code: #xF8 #x8F #xBF #xBD #x80", is > that not considered a leak? No. You created this yourself, and got what you asked for. More generally, can you imagine a real-life situation where a string with such "bytes" could be received from a module, as part of a C 'char *' string? > You are suggesting to expose the internal representation to outside > application code, which predictably will cause that representation to > leak into Lisp. That'd be a disaster. We had something like that > back in the Emacs 20 era, and it took many years to plug those leaks. > We would be making a grave mistake to go back there. > > I don't suggest leaking anything what isn't already leaked. The extension of > the codespace to 22 bits is well documented. I don't think it's reasonable to request that module authors read all that stuff and understand it, before they can write a simple module that manipulates non-ASCII text. Writing such modules should be that hard. > Returning raw bytes means that encoding and decoding isn't a perfect roundtrip: > > (decode-coding-string (encode-coding-string (string #x3fffc2 #x3fffbb) > 'utf-8-unix) 'utf-8-unix) > "»" If you start with raw bytes, not large integers, then the roundtrip will be perfect. > What are the exact difference between the approaches? As far as I can see > differences exist only for the following points: > - Accepting invalid sequences. I consider that a bug in general-purpose APIs, > including decode-coding-string. However, given that Emacs already extends the > Unicode codespace and therefore has to accept some invalid sequences anyway, it > might be OK if it's clearly documented. > - Emitting raw bytes instead of extended sequences. Though I'm not a fan of > this it might be unavoidable to be able to treat strings transparently (which > is desirable). Then I think we agree after all. Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 9:25 ` Philipp Stephani 2015-11-22 14:56 ` Philipp Stephani @ 2015-11-22 17:35 ` Eli Zaretskii 2015-11-22 18:19 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-22 17:35 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sun, 22 Nov 2015 09:25:08 +0000 > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, emacs-devel@gnu.org > > > Fine with me, but how would we then represent Emacs strings that are not > valid > > Unicode strings? Just raise an error? > > No need to raise an error. Strings that are returned to modules > should be encoded into UTF-8. That encoding already takes care of > these situations: it either produces the UTF-8 encoding of the > equivalent Unicode characters, or outputs raw bytes. > > Then we should document such a situation and give module authors a way to > detect them. I already suggested what we should say in the documentation: that these interfaces accept and produce UTF-8 encoded non-ASCII text. > For example, what happens if a sequence of such raw bytes happens > to be a valid UTF-8 sequence? Is there a way for module code to detect this > situation? How can you detect that if you are only given the byte stream? You can't. You need some additional information to be able to distinguish between these two alternatives. Look, an Emacs module _must_ support non-ASCII text, otherwise it would be severely limited, to say the least. Having interfaces that accept and produce UTF-8 encoded strings is the simplest complete solution to this problem. So we must at least support that much. Supporting strings of raw bytes is also possible, probably even desirable, but it's an extension, something that would be required much more rarely. Such strings cannot be meaningfully treated as text: you cannot ask if some byte is upper-case or lower-case letter, you cannot display such strings as readable text, you cannot count characters in it, etc. Such strings are useful for a limited number of specialized jobs, and handling them in Lisp requires some caution, because if you treat them as normal text strings, you get surprises. So let's solve the more important issues first, and talk about extensions later. The more important issue is how can a module pass to Emacs non-ASCII text and get back non-ASCII text. And the answer to that is to use UTF-8 encoded strings. > We are quite capable of quietly accepting such strings, so that is > what I would suggest. Doing so would be in line with what Emacs does > when such invalid sequences come from other sources, like files. > > If we accept such strings, then we should document what the extensions are. > - Are UTF-8-like sequences encoding surrogate code points accepted? > - Are UTF-8-like sequences encoding integers outside the Unicode codespace > accepted? > - Are non-shortest forms accepted? > - Are other invalid code unit sequences accepted? _Anything_ can be accepted. _Any_ byte sequence. Emacs will cope. The perpetrator will probably get back after processing a string that is not entirely human-readable, or its processing will sometimes produce surprises, like if the string is lower-cased. But nothing bad will happen to Emacs, it won't crash and won't garble its display. Moreover, just passing such a string to Emacs, then outputting it back without any changes will produce an exact copy of the input, which is quite a feat, considering that the input was "invalid". If you want to see what "bad" things can happen, take a Latin-1 encoded FILE and visit it with "C-x RET c utf-8 RET C-x C-f FILE RET". Then play with the buffer a while. This is what happens when Emacs is told the text is in UTF-8, when it really isn't. There's no catastrophe, but the luser who does that might be amply punished, at the very least she will not see the letters she expects. However, if you save such a buffer to a file, using UTF-8, you will get the same Latin-1 encoded text as was there originally. Now, given such resilience, why do we need to raise an error? > If the answer to any of these is "yes", we can't say we accept UTF-8, because > we don't. We _expect_ UTF-8, and if given that, will produce known, predictable results when the string is processed as text. We can _tolerate_ violations, resulting in somewhat surprising behavior, if such a text is treated as "normal" human-readable text. (If the module knows what it does, and really means to work with raw bytes, then Emacs will do what the module expects, and produce raw bytes on output, as expected.) > Rather we should say what is actually accepted. Saying that is meaningless in this case, because we can accept anything. _If_ the module wants the string it passes to be processed as human-readable text that consists of recognizable characters, then the module should _only_ pass valid UTF-8 sequences. But raising errors upon detecting violations was discovered long ago a bad idea that users resented. So we don't, and neither should the module API. > > * If copy_string_contents is passed an Emacs string that is not a valid > Unicode > > string, what should happen? > > How can that happen? The Emacs string comes from the Emacs bowels, so > it must be "valid" string by Emacs standards. Or maybe I don't > understand what you mean by "invalid Unicode string". > > A sequence of integers where at least one element is not a Unicode scalar > value. Emacs doesn't store characters as scalar Unicode values, so this doesn't really explain to me your concept of a "valid Unicode string". > In any case, we already deal with any such problems when we save a > buffer to a file, or send it over the network. This isn't some new > problem we need to cope with. > > Yes, but the module interface is new, it doesn't necessarily have to have the > same behavior. Of course, it does! Modules are Emacs extensions, so the interface should support the same features that core Emacs does. Why? because there's no limits to what creative minds can do with this feature, so we should not artificially impose such limitations where we have sound, time-proven infrastructure that doesn't need them. > If we say we emit only UTF-8, then we should do so. We emit only valid UTF-8, provided that its source (if it came from a module) was valid UTF-8. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 17:35 ` Eli Zaretskii @ 2015-11-22 18:19 ` Philipp Stephani 2015-11-22 19:12 ` David Kastrup 2015-11-22 19:20 ` Eli Zaretskii 0 siblings, 2 replies; 765+ messages in thread From: Philipp Stephani @ 2015-11-22 18:19 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 8151 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am So., 22. Nov. 2015 um 18:35 Uhr: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Sun, 22 Nov 2015 09:25:08 +0000 > > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, > emacs-devel@gnu.org > > > > > Fine with me, but how would we then represent Emacs strings that > are not > > valid > > > Unicode strings? Just raise an error? > > > > No need to raise an error. Strings that are returned to modules > > should be encoded into UTF-8. That encoding already takes care of > > these situations: it either produces the UTF-8 encoding of the > > equivalent Unicode characters, or outputs raw bytes. > > > > Then we should document such a situation and give module authors a way to > > detect them. > > I already suggested what we should say in the documentation: that > these interfaces accept and produce UTF-8 encoded non-ASCII text. > If the interface accepts UTF-8, then it must signal an error for invalid sequences; the Unicode standard mandates this. If the interface produces UTF-8, then it must only ever produce valid sequences, this is again required by the Unicode standard. > > > For example, what happens if a sequence of such raw bytes happens > > to be a valid UTF-8 sequence? Is there a way for module code to detect > this > > situation? > > How can you detect that if you are only given the byte stream? You > can't. You need some additional information to be able to distinguish > between these two alternatives. > That's why I propose to not encode raw bytes as bytes, but as the Emacs integer codes used to represent them. > > Look, an Emacs module _must_ support non-ASCII text, otherwise it > would be severely limited, to say the least. Absolutely! > Having interfaces that > accept and produce UTF-8 encoded strings is the simplest complete > solution to this problem. So we must at least support that much. > Agreed. > > Supporting strings of raw bytes is also possible, probably even > desirable, but it's an extension, something that would be required > much more rarely. Such strings cannot be meaningfully treated as > text: you cannot ask if some byte is upper-case or lower-case letter, > you cannot display such strings as readable text, you cannot count > characters in it, etc. Such strings are useful for a limited number > of specialized jobs, and handling them in Lisp requires some caution, > because if you treat them as normal text strings, you get surprises. > Yes. However, without an interface they are awkward to produce. > > So let's solve the more important issues first, and talk about > extensions later. The more important issue is how can a module pass > to Emacs non-ASCII text and get back non-ASCII text. And the answer > to that is to use UTF-8 encoded strings. > Full agreement. > > > We are quite capable of quietly accepting such strings, so that is > > what I would suggest. Doing so would be in line with what Emacs does > > when such invalid sequences come from other sources, like files. > > > > If we accept such strings, then we should document what the extensions > are. > > - Are UTF-8-like sequences encoding surrogate code points accepted? > > - Are UTF-8-like sequences encoding integers outside the Unicode > codespace > > accepted? > > - Are non-shortest forms accepted? > > - Are other invalid code unit sequences accepted? > > _Anything_ can be accepted. _Any_ byte sequence. Emacs will cope. > Not if they accept UTF-8. The Unicode standard rules out accepting invalid byte sequences. If any byte sequence is accepted, then the behavior becomes more complex. We need to exhaustively describe the behavior for any possible byte sequence, otherwise module authors cannot make any assumption. > The perpetrator will probably get back after processing a string that > is not entirely human-readable, or its processing will sometimes > produce surprises, like if the string is lower-cased. But nothing bad > will happen to Emacs, it won't crash and won't garble its display. > Moreover, just passing such a string to Emacs, then outputting it back > without any changes will produce an exact copy of the input, which is > quite a feat, considering that the input was "invalid". > > If you want to see what "bad" things can happen, take a Latin-1 > encoded FILE and visit it with "C-x RET c utf-8 RET C-x C-f FILE RET". > Then play with the buffer a while. This is what happens when Emacs is > told the text is in UTF-8, when it really isn't. There's no > catastrophe, but the luser who does that might be amply punished, at > the very least she will not see the letters she expects. However, if > you save such a buffer to a file, using UTF-8, you will get the same > Latin-1 encoded text as was there originally. > > Now, given such resilience, why do we need to raise an error? > The Unicode standard says so. If we document that *a superset of UTF-8* is accepted, then we don't need to raise an error. So I'd suggest we do exactly that, but describe what that superset is. > > > If the answer to any of these is "yes", we can't say we accept UTF-8, > because > > we don't. > > We _expect_ UTF-8, and if given that, will produce known, predictable > results when the string is processed as text. We can _tolerate_ > violations, resulting in somewhat surprising behavior, if such a text > is treated as "normal" human-readable text. (If the module knows what > it does, and really means to work with raw bytes, then Emacs will do > what the module expects, and produce raw bytes on output, as > expected.) > No matter what we expect or tolerate, we need to state that. If all byte sequences are accepted, then we also need to state that, but describe what the behavior is if there are invalid UTF-8 sequences in the input. > > > Rather we should say what is actually accepted. > > Saying that is meaningless in this case, because we can accept > anything. _If_ the module wants the string it passes to be processed > as human-readable text that consists of recognizable characters, then > the module should _only_ pass valid UTF-8 sequences. But raising > errors upon detecting violations was discovered long ago a bad idea > that users resented. So we don't, and neither should the module API. > Module authors are not end users. I agree that end users should not see errors on decoding failure, but modules use only programmatic access, where we can be more strict. > > > > * If copy_string_contents is passed an Emacs string that is not a > valid > > Unicode > > > string, what should happen? > > > > How can that happen? The Emacs string comes from the Emacs bowels, so > > it must be "valid" string by Emacs standards. Or maybe I don't > > understand what you mean by "invalid Unicode string". > > > > A sequence of integers where at least one element is not a Unicode scalar > > value. > > Emacs doesn't store characters as scalar Unicode values, so this > doesn't really explain to me your concept of a "valid Unicode string". > An Emacs string is a sequence of integers. It doesn't have to be a sequence of scalar values. > > > In any case, we already deal with any such problems when we save a > > buffer to a file, or send it over the network. This isn't some new > > problem we need to cope with. > > > > Yes, but the module interface is new, it doesn't necessarily have to > have the > > same behavior. > > Of course, it does! Modules are Emacs extensions, so the interface > should support the same features that core Emacs does. Why? because > there's no limits to what creative minds can do with this feature, so > we should not artificially impose such limitations where we have > sound, time-proven infrastructure that doesn't need them. > I agree that we shouldn't add such limitations. But I disagree that we should leave the behavior undocumented in such cases. > > > If we say we emit only UTF-8, then we should do so. > > We emit only valid UTF-8, provided that its source (if it came from a > module) was valid UTF-8. > Then in turn we shouldn't say we emit only UTF-8. [-- Attachment #2: Type: text/html, Size: 11250 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 18:19 ` Philipp Stephani @ 2015-11-22 19:12 ` David Kastrup 2015-11-22 19:20 ` Eli Zaretskii 1 sibling, 0 replies; 765+ messages in thread From: David Kastrup @ 2015-11-22 19:12 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, Eli Zaretskii, tzz, emacs-devel Philipp Stephani <p.stephani2@gmail.com> writes: > Eli Zaretskii <eliz@gnu.org> schrieb am So., 22. Nov. 2015 um 18:35 Uhr: > >> > From: Philipp Stephani <p.stephani2@gmail.com> >> > Date: Sun, 22 Nov 2015 09:25:08 +0000 >> > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, >> emacs-devel@gnu.org >> > >> > > Fine with me, but how would we then represent Emacs strings that >> are not >> > valid >> > > Unicode strings? Just raise an error? >> > >> > No need to raise an error. Strings that are returned to modules >> > should be encoded into UTF-8. That encoding already takes care of >> > these situations: it either produces the UTF-8 encoding of the >> > equivalent Unicode characters, or outputs raw bytes. >> > >> > Then we should document such a situation and give module authors a way to >> > detect them. >> >> I already suggested what we should say in the documentation: that >> these interfaces accept and produce UTF-8 encoded non-ASCII text. >> > > If the interface accepts UTF-8, then it must signal an error for invalid > sequences; the Unicode standard mandates this. > If the interface produces UTF-8, then it must only ever produce valid > sequences, this is again required by the Unicode standard. The Unicode standard does not mandate Emacs' internal string encodings. Emacs 22 had an entirely different internal string encoding that was less convenient for a module interface. Emacs' internal encoding has the property that valid UTF-8 sequences are represented by themselves. Which is a convenience to the programmer. Not more, not less. > That's why I propose to not encode raw bytes as bytes, but as the > Emacs integer codes used to represent them. So UCS-16 instead of UTF-8? With conversions for every call? That sounds like shuffling the problem around, and shuffling does not come for free. It's ok to provide checking sequences that verify that something is a valid internal Emacs string (which includes more than Unicode) and flag an error if it isn't. Also that something is a valid UTF-8 string if that is desired (and which will in case of error optionally either convert to the Emacs-internal representation or flag an error). But making each call gate automatically verify every string for UTF-8 compliance is both wasteful as well as making it impossible to process generic Emacs strings in an external module. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 18:19 ` Philipp Stephani 2015-11-22 19:12 ` David Kastrup @ 2015-11-22 19:20 ` Eli Zaretskii 2015-11-22 19:37 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-22 19:20 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sun, 22 Nov 2015 18:19:29 +0000 > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, emacs-devel@gnu.org > > I already suggested what we should say in the documentation: that > these interfaces accept and produce UTF-8 encoded non-ASCII text. > > > If the interface accepts UTF-8, then it must signal an error for invalid > sequences; the Unicode standard mandates this. The Unicode standard cannot mandate anything for Emacs, because Emacs is not subject to Unicode standardization. > If the interface produces UTF-8, then it must only ever produce valid > sequences As I explained, this would violate the basic expectation from a text editing program. > That's why I propose to not encode raw bytes as bytes, but as the Emacs integer > codes used to represent them. If we do that, no external code will be able to do anything useful with such "bytes". Module authors will have to write their own replacements for library functions. This will never be accepted by our users. > If any byte sequence is accepted, then the behavior becomes more complex. We > need to exhaustively describe the behavior for any possible byte sequence, > otherwise module authors cannot make any assumption. We say that we accept valid UTF-8 encoded strings; anything else might produce invalid UTF-8 on output. > No matter what we expect or tolerate, we need to state that. No, we don't. When the callers violate the contract, they cannot expect to know in detail what will happen. If they want to know, they will have to read the source. > Module authors are not end users. They are users like anyone who writes Lisp. They came to expect that Emacs behaves in certain ways, and modules should follow suit. > I agree that end users should not see errors on decoding failure, > but modules use only programmatic access, where we can be more > strict. You cannot be more strict, unless you rewrite the whole encoding/decoding machinery, or write specialized code to detect and reject invalid UTF-8 before it is passed to a decoder. There are no good reasons to do either, so let's not. > An Emacs string is a sequence of integers. No, it's a sequence of bytes. > I agree that we shouldn't add such limitations. But I disagree that we should > leave the behavior undocumented in such cases. OK, so let's agree to disagree. If that disagreement gets in your way of fixing the issues related to this discussion, please say so, and I will fix them myself Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 19:20 ` Eli Zaretskii @ 2015-11-22 19:37 ` Philipp Stephani 2015-11-22 19:49 ` David Kastrup 2015-11-22 19:50 ` Eli Zaretskii 0 siblings, 2 replies; 765+ messages in thread From: Philipp Stephani @ 2015-11-22 19:37 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1: Type: text/plain, Size: 3763 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am So., 22. Nov. 2015 um 20:20 Uhr: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Sun, 22 Nov 2015 18:19:29 +0000 > > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, > emacs-devel@gnu.org > > > > I already suggested what we should say in the documentation: that > > these interfaces accept and produce UTF-8 encoded non-ASCII text. > > > > > > If the interface accepts UTF-8, then it must signal an error for invalid > > sequences; the Unicode standard mandates this. > > The Unicode standard cannot mandate anything for Emacs, because Emacs > is not subject to Unicode standardization. > True, but I think we shouldn't make the terminology more confusing. If we say "UTF-8", we should mean "UTF-8 as defined in the Unicode standard", not the Emacs extension of UTF-8. That's all. > > > If the interface produces UTF-8, then it must only ever produce valid > > sequences > > As I explained, this would violate the basic expectation from a text > editing program. > > > That's why I propose to not encode raw bytes as bytes, but as the Emacs > integer > > codes used to represent them. > > If we do that, no external code will be able to do anything useful > with such "bytes". Module authors will have to write their own > replacements for library functions. This will never be accepted by > our users. > I wouldn't be so pessimistic, but I was convinced by consistency with encode-coding-string. So yes, let's use the raw bytes (and document that). > > > If any byte sequence is accepted, then the behavior becomes more > complex. We > > need to exhaustively describe the behavior for any possible byte > sequence, > > otherwise module authors cannot make any assumption. > > We say that we accept valid UTF-8 encoded strings; anything else > might produce invalid UTF-8 on output. > Couldn't we just say "it behaves as if encoding and decoding were done using the utf-8-unix coding system"? Because I think that's what this boils down to. > > > No matter what we expect or tolerate, we need to state that. > > No, we don't. When the callers violate the contract, they cannot > expect to know in detail what will happen. If they want to know, they > will have to read the source. > So you want this to be unspecified or undefined behavior? That might be OK (we already have that in several places), but we still need to state what the contract is. > > > Module authors are not end users. > > They are users like anyone who writes Lisp. They came to expect that > Emacs behaves in certain ways, and modules should follow suit. > > > I agree that end users should not see errors on decoding failure, > > but modules use only programmatic access, where we can be more > > strict. > > You cannot be more strict, unless you rewrite the whole > encoding/decoding machinery, or write specialized code to detect and > reject invalid UTF-8 before it is passed to a decoder. There are no > good reasons to do either, so let's not. > > > An Emacs string is a sequence of integers. > > No, it's a sequence of bytes. > From https://www.gnu.org/software/emacs/manual/html_node/elisp/String-Basics.html : "In Emacs Lisp, characters are simply integers ... A string is a fixed sequence of characters" How a string is represented internally shouldn't be the concern of module authors. > > > I agree that we shouldn't add such limitations. But I disagree that we > should > > leave the behavior undocumented in such cases. > > OK, so let's agree to disagree. If that disagreement gets in your way > of fixing the issues related to this discussion, please say so, and I > will fix them myself > > No, I will definitely fix it. I think our disagreement is way smaller than it might look like. [-- Attachment #2: Type: text/html, Size: 5521 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 19:37 ` Philipp Stephani @ 2015-11-22 19:49 ` David Kastrup 2015-11-22 19:50 ` Eli Zaretskii 1 sibling, 0 replies; 765+ messages in thread From: David Kastrup @ 2015-11-22 19:49 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, Eli Zaretskii, tzz, emacs-devel Philipp Stephani <p.stephani2@gmail.com> writes: >> > An Emacs string is a sequence of integers. >> >> No, it's a sequence of bytes. >> > > From > https://www.gnu.org/software/emacs/manual/html_node/elisp/String-Basics.html > : > "In Emacs Lisp, characters are simply integers ... A string is a fixed > sequence of characters" > How a string is represented internally shouldn't be the concern of module > authors. Except that we are not talking about modules written in Emacs Lisp. The qualifier "In Emacs Lisp" does not hold here. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 19:37 ` Philipp Stephani 2015-11-22 19:49 ` David Kastrup @ 2015-11-22 19:50 ` Eli Zaretskii 2015-11-22 20:59 ` David Kastrup 2015-11-22 21:10 ` Philipp Stephani 1 sibling, 2 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-22 19:50 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sun, 22 Nov 2015 19:37:43 +0000 > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, emacs-devel@gnu.org > > I think we shouldn't make the terminology more confusing. If we say > "UTF-8", we should mean "UTF-8 as defined in the Unicode standard", not the > Emacs extension of UTF-8. That's all. I agree, and that's how I use "UTF-8". The internal representation used by Emacs is called "utf-8-emacs" or "emacs-internal". > We say that we accept valid UTF-8 encoded strings; anything else > might produce invalid UTF-8 on output. > > Couldn't we just say "it behaves as if encoding and decoding were done using > the utf-8-unix coding system"? Because I think that's what this boils down to. Not sure what you mean by "utf-8-unix", or why it would be better to say that. I think this makes the issue harder to understand, because it involves a reference to the encoding/decoding stuff, something that module authors might not be fluent with. > > No matter what we expect or tolerate, we need to state that. > > No, we don't. When the callers violate the contract, they cannot > expect to know in detail what will happen. If they want to know, they > will have to read the source. > > So you want this to be unspecified or undefined behavior? That might be OK (we > already have that in several places), but we still need to state what the > contract is. You can call it "undefined behavior" if you want. Personally, I don't think that's accurate: "undefined" means anything can happen, whereas Emacs at least promises to output the original bytes unchanged, as long as the text modifications didn't touch them. > > An Emacs string is a sequence of integers. > > No, it's a sequence of bytes. > > From > https://www.gnu.org/software/emacs/manual/html_node/elisp/String-Basics.html: > "In Emacs Lisp, characters are simply integers ... A string is a fixed sequence > of characters" That's the _User_ manual, it simplifies things to avoid too much complexity. > How a string is represented internally shouldn't be the concern of module > authors. Indeed. But it does concern us, the developers of Emacs internals. > No, I will definitely fix it. Thank you. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 19:50 ` Eli Zaretskii @ 2015-11-22 20:59 ` David Kastrup 2015-11-23 3:29 ` Eli Zaretskii 2015-11-22 21:10 ` Philipp Stephani 1 sibling, 1 reply; 765+ messages in thread From: David Kastrup @ 2015-11-22 20:59 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, Philipp Stephani, tzz, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: Philipp Stephani <p.stephani2@gmail.com> > >> > No matter what we expect or tolerate, we need to state that. >> >> No, we don't. When the callers violate the contract, they cannot >> expect to know in detail what will happen. If they want to know, they >> will have to read the source. >> >> So you want this to be unspecified or undefined behavior? That might be OK (we >> already have that in several places), but we still need to state what the >> contract is. > > You can call it "undefined behavior" if you want. Personally, I don't > think that's accurate: "undefined" means anything can happen, whereas > Emacs at least promises to output the original bytes unchanged, as > long as the text modifications didn't touch them. Uh, no? After converting from utf-8-unix to emacs-internal, Emacs' own processing will not affect originally bad sequences in utf-8-unix. However, that would require all string passing to include a decoding/encoding step so that the nominal encoding used by the module is utf-8-unix. I think in the interest of both roundtrip times as well as general usefulness of modules, it would be better if the default communication encoding with the module would indeed be emacs-internal. That way, modules can solve problems outside of Unicode proper. This is definitely not a no-brainer: choosing utf-8-unix as the communication encoding for modules would be an interface with less dependency on Emacs' coding internals but it would pin down UTF-8 as the only actual useful encoding modules could be made to deal with and would incur performance penalties. -- David Kastrup ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 20:59 ` David Kastrup @ 2015-11-23 3:29 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-23 3:29 UTC (permalink / raw) To: David Kastrup; +Cc: aurelien.aptel+emacs, p.stephani2, tzz, emacs-devel > From: David Kastrup <dak@gnu.org> > Cc: Philipp Stephani <p.stephani2@gmail.com>, aurelien.aptel+emacs@gmail.com, tzz@lifelogs.com, emacs-devel@gnu.org > Date: Sun, 22 Nov 2015 21:59:43 +0100 > > > You can call it "undefined behavior" if you want. Personally, I don't > > think that's accurate: "undefined" means anything can happen, whereas > > Emacs at least promises to output the original bytes unchanged, as > > long as the text modifications didn't touch them. > > Uh, no? After converting from utf-8-unix to emacs-internal, Emacs' own > processing will not affect originally bad sequences in utf-8-unix. > However, that would require all string passing to include a > decoding/encoding step so that the nominal encoding used by the module > is utf-8-unix. That's exactly what I am proposing. > I think in the interest of both roundtrip times as well as general > usefulness of modules, it would be better if the default communication > encoding with the module would indeed be emacs-internal. No! Modules cannot convert non-ASCII text into emacs-internal (we don't expose the coding.c functionality through the API), and shouldn't have to. That is the job of the interface. > That way, modules can solve problems outside of Unicode proper. What problems are those? > This is definitely not a no-brainer: choosing utf-8-unix as the > communication encoding for modules would be an interface with less > dependency on Emacs' coding internals but it would pin down UTF-8 as the > only actual useful encoding modules could be made to deal with and would > incur performance penalties. That's exactly what's being proposed. But utf-8-unix is NOT the internal encoding, it's the Unicode-mandated UTF-8. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 19:50 ` Eli Zaretskii 2015-11-22 20:59 ` David Kastrup @ 2015-11-22 21:10 ` Philipp Stephani 2015-11-23 3:31 ` Eli Zaretskii 2015-11-23 18:10 ` Eli Zaretskii 1 sibling, 2 replies; 765+ messages in thread From: Philipp Stephani @ 2015-11-22 21:10 UTC (permalink / raw) To: Eli Zaretskii; +Cc: aurelien.aptel+emacs, tzz, emacs-devel [-- Attachment #1.1: Type: text/plain, Size: 1656 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am So., 22. Nov. 2015 um 20:51 Uhr: > > > No matter what we expect or tolerate, we need to state that. > > > > No, we don't. When the callers violate the contract, they cannot > > expect to know in detail what will happen. If they want to know, they > > will have to read the source. > > > > So you want this to be unspecified or undefined behavior? That might be > OK (we > > already have that in several places), but we still need to state what the > > contract is. > > You can call it "undefined behavior" if you want. Personally, I don't > think that's accurate: "undefined" means anything can happen, whereas > Emacs at least promises to output the original bytes unchanged, as > long as the text modifications didn't touch them. > "Unspecified" would fit the bill better. Actually for most interesting inputs (UTF-8 strings) the behavior is well-defined anyway. > > > > An Emacs string is a sequence of integers. > > > > No, it's a sequence of bytes. > > > > From > > > https://www.gnu.org/software/emacs/manual/html_node/elisp/String-Basics.html > : > > "In Emacs Lisp, characters are simply integers ... A string is a fixed > sequence > > of characters" > > That's the _User_ manual, it simplifies things to avoid too much > complexity. > So where's the programmer's manual then? The source code? ;-) > > > How a string is represented internally shouldn't be the concern of module > > authors. > > Indeed. But it does concern us, the developers of Emacs internals. > > > No, I will definitely fix it. > > Thank you. > Attached a patch that uses make_multibyte_string directly. [-- Attachment #1.2: Type: text/html, Size: 2604 bytes --] [-- Attachment #2: 0001-Improvements-to-string-conversions.patch --] [-- Type: application/octet-stream, Size: 3773 bytes --] From 6e5b055078fe7155c871a1b68257d3705aeb2ceb Mon Sep 17 00:00:00 2001 From: Philipp Stephani <phst@google.com> Date: Sun, 22 Nov 2015 22:07:40 +0100 Subject: [PATCH] Improvements to string conversions * emacs-module.c (module_make_function, module_make_string): Use make_multibyte_string. (module_copy_string_contents): Encode before reading the byte size. Return false if and only if an error occurred. --- src/emacs-module.c | 52 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/src/emacs-module.c b/src/emacs-module.c index c8a0d89..f49802c 100644 --- a/src/emacs-module.c +++ b/src/emacs-module.c @@ -25,6 +25,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ #include <stddef.h> #include <stdint.h> #include <stdio.h> +#include <string.h> #include "lisp.h" #include "dynlib.h" @@ -386,9 +387,20 @@ module_make_function (emacs_env *env, ptrdiff_t min_arity, ptrdiff_t max_arity, envptr->data = data; Lisp_Object envobj = make_save_ptr (envptr); + Lisp_Object doc; + if (documentation == NULL) + doc = Qnil; + else + { + ptrdiff_t nbytes = strlen (documentation); + ptrdiff_t nchars, ignored_nbytes; + parse_str_as_multibyte (documentation, nbytes, &nchars, &ignored_nbytes); + doc = make_multibyte_string (documentation, nchars, nbytes); + } + Lisp_Object ret = list4 (Qlambda, list2 (Qand_rest, Qargs), - documentation ? build_string (documentation) : Qnil, + doc, list3 (module_call_func, envobj, Qargs)); @@ -515,21 +527,34 @@ module_copy_string_contents (emacs_env *env, emacs_value value, char *buffer, return false; } - ptrdiff_t raw_size = SBYTES (lisp_str); + Lisp_Object lisp_str_utf8 = ENCODE_UTF_8 (lisp_str); + ptrdiff_t raw_size = SBYTES (lisp_str_utf8); + if (raw_size == PTRDIFF_MAX) + { + module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); + return false; + } + ptrdiff_t required_buf_size = raw_size + 1; + + eassert (length != NULL); - /* Emacs internal encoding is more-or-less UTF8, let's assume utf8 - encoded emacs string are the same byte size. */ + if (buffer == NULL) + { + *length = required_buf_size; + return true; + } + + eassert (*length >= 0); - if (!buffer || length == 0 || *length-1 < raw_size) + if (*length < required_buf_size) { - *length = raw_size + 1; + *length = required_buf_size; + module_non_local_exit_signal_1 (env, Qargs_out_of_range, Qnil); return false; } - Lisp_Object lisp_str_utf8 = ENCODE_UTF_8 (lisp_str); - eassert (raw_size == SBYTES (lisp_str_utf8)); - *length = raw_size + 1; - memcpy (buffer, SDATA (lisp_str_utf8), SBYTES (lisp_str_utf8)); + *length = required_buf_size; + memcpy (buffer, SDATA (lisp_str_utf8), raw_size); buffer[raw_size] = 0; return true; @@ -541,13 +566,14 @@ module_make_string (emacs_env *env, const char *str, ptrdiff_t length) check_main_thread (); eassert (module_non_local_exit_check (env) == emacs_funcall_exit_return); MODULE_HANDLE_SIGNALS; - if (length > PTRDIFF_MAX) + if (length > STRING_BYTES_BOUND) { module_non_local_exit_signal_1 (env, Qoverflow_error, Qnil); return NULL; } - /* Assume STR is utf8 encoded. */ - return lisp_to_value (env, make_string (str, length)); + ptrdiff_t nchars, ignored_nbytes; + parse_str_as_multibyte (str, length, &nchars, &ignored_nbytes); + return lisp_to_value (env, make_multibyte_string (str, nchars, length)); } static emacs_value -- 2.6.3 ^ permalink raw reply related [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 21:10 ` Philipp Stephani @ 2015-11-23 3:31 ` Eli Zaretskii 2015-11-23 18:10 ` Eli Zaretskii 1 sibling, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-23 3:31 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sun, 22 Nov 2015 21:10:58 +0000 > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, emacs-devel@gnu.org > > You can call it "undefined behavior" if you want. Personally, I don't > think that's accurate: "undefined" means anything can happen, whereas > Emacs at least promises to output the original bytes unchanged, as > long as the text modifications didn't touch them. > > "Unspecified" would fit the bill better. Actually for most interesting inputs > (UTF-8 strings) the behavior is well-defined anyway. Correct. > That's the _User_ manual, it simplifies things to avoid too much > complexity. > > So where's the programmer's manual then? The source code? ;-) There's the ELisp manual, yes. It should be more accurate in this regard. > Attached a patch that uses make_multibyte_string directly. Looks good to me, thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-22 21:10 ` Philipp Stephani 2015-11-23 3:31 ` Eli Zaretskii @ 2015-11-23 18:10 ` Eli Zaretskii 1 sibling, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-23 18:10 UTC (permalink / raw) To: Philipp Stephani; +Cc: aurelien.aptel+emacs, tzz, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sun, 22 Nov 2015 21:10:58 +0000 > Cc: tzz@lifelogs.com, aurelien.aptel+emacs@gmail.com, emacs-devel@gnu.org > > Attached a patch that uses make_multibyte_string directly. Thanks, pushed. On further thought, I concluded that making a unibyte string and then decoding it explicitly by UTF-8 is more tolerant to deviations from UTF-8, so I made that change in a follow-up commit. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 3:39 ` Eli Zaretskii 2015-11-19 15:26 ` Eli Zaretskii @ 2015-11-19 22:14 ` Philipp Stephani 2015-11-23 16:57 ` Ted Zlatanov 1 sibling, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-19 22:14 UTC (permalink / raw) To: Eli Zaretskii, emacs-devel [-- Attachment #1: Type: text/plain, Size: 462 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am Do., 19. Nov. 2015 um 04:39 Uhr: > I think the place is the ELisp manual. I see no reason to have a > separate manual, since I don't expect the documentation to be large > enough to justify that. > Agreed. I've started to write some reference manual, but that is more of a mnemonic device for me to remember what the exact behavior of each function should be. I hope to come up with some user-level documentation soon. [-- Attachment #2: Type: text/html, Size: 745 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 22:14 ` Philipp Stephani @ 2015-11-23 16:57 ` Ted Zlatanov 0 siblings, 0 replies; 765+ messages in thread From: Ted Zlatanov @ 2015-11-23 16:57 UTC (permalink / raw) To: emacs-devel On Thu, 19 Nov 2015 22:14:15 +0000 Philipp Stephani <p.stephani2@gmail.com> wrote: PS> Eli Zaretskii <eliz@gnu.org> schrieb am Do., 19. Nov. 2015 um 04:39 Uhr: >> I think the place is the ELisp manual. I see no reason to have a >> separate manual, since I don't expect the documentation to be large >> enough to justify that. PS> Agreed. I've started to write some reference manual, but that is more of a PS> mnemonic device for me to remember what the exact behavior of each function PS> should be. I hope to come up with some user-level documentation soon. Please consider sharing it with me and Aurélien and possibly others so we can work on it together before merging it. It could live in a temporary Github branch of emacs.git for instance. Thanks Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 2:19 ` Ted Zlatanov 2015-11-19 3:39 ` Eli Zaretskii @ 2015-11-19 22:12 ` Philipp Stephani 2015-11-20 7:50 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-19 22:12 UTC (permalink / raw) To: emacs-devel [-- Attachment #1: Type: text/plain, Size: 874 bytes --] Ted Zlatanov <tzz@lifelogs.com> schrieb am Do., 19. Nov. 2015 um 03:19 Uhr: > EZ> Of course! Every feature should be documented, and this one is no > EZ> exception. I suggest to start with NEWS. > > My goal with that question was actually to find out *where* the > developer docs should go, not whether they are necessary. I think we > all agree on the necessity. I can try a first stab at them when I know > in what context they'll exist. > > Regarding NEWS specifically, Aurélien is absent at the moment and will > be back next week. Maybe Philipp would like to provide the NEWS entries? > I will write them if neither of them is able or if it can't wait until > next week. > I can see whether I can come up with something. However as far as I can see the release of 25.1 is not imminent, so the documentation doesn't need to happen immediately. [-- Attachment #2: Type: text/html, Size: 1182 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-19 22:12 ` Philipp Stephani @ 2015-11-20 7:50 ` Eli Zaretskii 2015-11-20 22:10 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-20 7:50 UTC (permalink / raw) To: Philipp Stephani; +Cc: emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Thu, 19 Nov 2015 22:12:14 +0000 > > Regarding NEWS specifically, Aurélien is absent at the moment and will > be back next week. Maybe Philipp would like to provide the NEWS entries? > I will write them if neither of them is able or if it can't wait until > next week. > > > I can see whether I can come up with something. However as far as I can see the > release of 25.1 is not imminent, so the documentation doesn't need to happen > immediately. The documentation in the _manuals_ doesn't have to happen immediately, although it should be our goal to make that happen more frequently than it happens today: after all, those who use the development Emacs should also ideally have the manuals to go with that. But NEWS should have some minimal documentation of the new feature _immediately_, i.e. as part of the last commit of the feature. Otherwise, users will have no idea what is being added and how to use it, and frequently even not that it was in fact added. Thanks in advance. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 7:50 ` Eli Zaretskii @ 2015-11-20 22:10 ` Philipp Stephani 2015-11-20 23:46 ` Paul Eggert 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-20 22:10 UTC (permalink / raw) To: Eli Zaretskii; +Cc: emacs-devel [-- Attachment #1.1: Type: text/plain, Size: 1272 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am Fr., 20. Nov. 2015 um 08:50 Uhr: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Thu, 19 Nov 2015 22:12:14 +0000 > > > > Regarding NEWS specifically, Aurélien is absent at the moment and > will > > be back next week. Maybe Philipp would like to provide the NEWS > entries? > > I will write them if neither of them is able or if it can't wait > until > > next week. > > > > > > I can see whether I can come up with something. However as far as I can > see the > > release of 25.1 is not imminent, so the documentation doesn't need to > happen > > immediately. > > The documentation in the _manuals_ doesn't have to happen immediately, > although it should be our goal to make that happen more frequently > than it happens today: after all, those who use the development Emacs > should also ideally have the manuals to go with that. But NEWS should > have some minimal documentation of the new feature _immediately_, > i.e. as part of the last commit of the feature. Otherwise, users will > have no idea what is being added and how to use it, and frequently > even not that it was in fact added. > > Thanks in advance. > I've attached a preliminary patch for NEWS. [-- Attachment #1.2: Type: text/html, Size: 1707 bytes --] [-- Attachment #2: 0001-Add-NEWS-entry-for-modules.patch --] [-- Type: application/octet-stream, Size: 827 bytes --] From a9a8d868a04742faf8852a08d183b82eb3894a4b Mon Sep 17 00:00:00 2001 From: Philipp Stephani <phst@google.com> Date: Fri, 20 Nov 2015 22:06:05 +0100 Subject: [PATCH] Add NEWS entry for modules --- etc/NEWS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/etc/NEWS b/etc/NEWS index 9793d5e..fe0122a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -302,6 +302,12 @@ header. which specifies an alternative printing method which is faster when few or no entries have changed. +** Emacs can now load shared/dynamic libraries (modules) that expose a +C interface. Such modules can provide additional functions or +otherwise interact with Emacs just like Lisp code. Modules have to +export a function `emacs_module_init' and conform to the API laid out +in emacs-module.h. + \f * Editing Changes in Emacs 25.1 -- 2.6.3 ^ permalink raw reply related [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 22:10 ` Philipp Stephani @ 2015-11-20 23:46 ` Paul Eggert 2015-11-21 7:53 ` Eli Zaretskii 2015-11-21 8:30 ` Philipp Stephani 0 siblings, 2 replies; 765+ messages in thread From: Paul Eggert @ 2015-11-20 23:46 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii; +Cc: emacs-devel Philipp Stephani wrote: > I've attached a preliminary patch for NEWS. That text should also mention the --with-modules option of 'configure', and mention that modules are disabled by default, and that modules are currently experimental and subject to change. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 23:46 ` Paul Eggert @ 2015-11-21 7:53 ` Eli Zaretskii 2015-11-21 8:30 ` Philipp Stephani 1 sibling, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-21 7:53 UTC (permalink / raw) To: Paul Eggert; +Cc: p.stephani2, emacs-devel > Cc: emacs-devel@gnu.org > From: Paul Eggert <eggert@cs.ucla.edu> > Date: Fri, 20 Nov 2015 15:46:56 -0800 > > Philipp Stephani wrote: > > I've attached a preliminary patch for NEWS. > > That text should also mention the --with-modules option of 'configure', and > mention that modules are disabled by default, and that modules are currently > experimental and subject to change. Agreed. The parts about --with-modules and its being optional should go into the section of NEWS about installation changes. Thanks. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-20 23:46 ` Paul Eggert 2015-11-21 7:53 ` Eli Zaretskii @ 2015-11-21 8:30 ` Philipp Stephani 2015-11-21 9:06 ` Eli Zaretskii 1 sibling, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-21 8:30 UTC (permalink / raw) To: Paul Eggert, Eli Zaretskii; +Cc: emacs-devel [-- Attachment #1.1: Type: text/plain, Size: 380 bytes --] Paul Eggert <eggert@cs.ucla.edu> schrieb am Sa., 21. Nov. 2015 um 00:46 Uhr: > Philipp Stephani wrote: > > I've attached a preliminary patch for NEWS. > > That text should also mention the --with-modules option of 'configure', and > mention that modules are disabled by default, and that modules are > currently > experimental and subject to change. > OK, attached a new patch. [-- Attachment #1.2: Type: text/html, Size: 681 bytes --] [-- Attachment #2: 0001-Add-NEWS-entry-for-modules.patch --] [-- Type: application/octet-stream, Size: 1408 bytes --] From 33a51ab2526f0bce7f0e9bc06693f4db8401cf1a Mon Sep 17 00:00:00 2001 From: Philipp Stephani <phst@google.com> Date: Fri, 20 Nov 2015 22:06:05 +0100 Subject: [PATCH] Add NEWS entry for modules --- etc/NEWS | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/etc/NEWS b/etc/NEWS index 9793d5e..8ed8133 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -36,6 +36,9 @@ otherwise leave it unmarked. This builds Emacs with Cairo drawing. As a side effect, it provides support for built-in printing, when Emacs was built with GTK+. +** New configure option --with-modules. +This enables support for loading dynamic modules; see below. + --- ** By default, Emacs no longer works on IRIX. We expect that Emacs users are not affected by this, as SGI stopped supporting IRIX in @@ -302,6 +305,14 @@ header. which specifies an alternative printing method which is faster when few or no entries have changed. +** Emacs can now load shared/dynamic libraries (modules) that expose a +C interface. Such modules can provide additional functions or +otherwise interact with Emacs just like Lisp code. Modules have to +export a function `emacs_module_init' and conform to the API laid out +in emacs-module.h. Modules are disabled by default and need to be +enabled using the --with-modules configure flag. They are +experimental and subject to change. + \f * Editing Changes in Emacs 25.1 -- 2.6.3 ^ permalink raw reply related [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 8:30 ` Philipp Stephani @ 2015-11-21 9:06 ` Eli Zaretskii 2015-11-21 9:25 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-21 9:06 UTC (permalink / raw) To: Philipp Stephani; +Cc: eggert, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sat, 21 Nov 2015 08:30:11 +0000 > Cc: emacs-devel@gnu.org > > OK, attached a new patch. LGTM, please push. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 9:06 ` Eli Zaretskii @ 2015-11-21 9:25 ` Philipp Stephani 2015-11-21 9:51 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-21 9:25 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel [-- Attachment #1: Type: text/plain, Size: 350 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am Sa., 21. Nov. 2015 um 10:07 Uhr: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Sat, 21 Nov 2015 08:30:11 +0000 > > Cc: emacs-devel@gnu.org > > > > OK, attached a new patch. > > LGTM, please push. > I don't have write access to the Savannah repository, can you please install the patch for me? [-- Attachment #2: Type: text/html, Size: 776 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 9:25 ` Philipp Stephani @ 2015-11-21 9:51 ` Eli Zaretskii 2015-11-21 10:33 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Eli Zaretskii @ 2015-11-21 9:51 UTC (permalink / raw) To: Philipp Stephani; +Cc: eggert, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sat, 21 Nov 2015 09:25:09 +0000 > Cc: eggert@cs.ucla.edu, emacs-devel@gnu.org > > LGTM, please push. > > I don't have write access to the Savannah repository, can you please install > the patch for me? Done. Btw, I see you don't have a copyright assignment on file. Would you like to start the paperwork to do that now, so that your future contributions won't stall? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 9:51 ` Eli Zaretskii @ 2015-11-21 10:33 ` Philipp Stephani 2015-11-21 10:53 ` Eli Zaretskii 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-21 10:33 UTC (permalink / raw) To: Eli Zaretskii; +Cc: eggert, emacs-devel [-- Attachment #1: Type: text/plain, Size: 610 bytes --] Eli Zaretskii <eliz@gnu.org> schrieb am Sa., 21. Nov. 2015 um 10:52 Uhr: > > From: Philipp Stephani <p.stephani2@gmail.com> > > Date: Sat, 21 Nov 2015 09:25:09 +0000 > > Cc: eggert@cs.ucla.edu, emacs-devel@gnu.org > > > > LGTM, please push. > > > > I don't have write access to the Savannah repository, can you please > install > > the patch for me? > > Done. > > Btw, I see you don't have a copyright assignment on file. Would you > like to start the paperwork to do that now, so that your future > contributions won't stall? > My contributions are covered by the agreement between Google and the FSF. [-- Attachment #2: Type: text/html, Size: 1133 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-21 10:33 ` Philipp Stephani @ 2015-11-21 10:53 ` Eli Zaretskii 0 siblings, 0 replies; 765+ messages in thread From: Eli Zaretskii @ 2015-11-21 10:53 UTC (permalink / raw) To: Philipp Stephani; +Cc: eggert, emacs-devel > From: Philipp Stephani <p.stephani2@gmail.com> > Date: Sat, 21 Nov 2015 10:33:15 +0000 > Cc: eggert@cs.ucla.edu, emacs-devel@gnu.org > > Btw, I see you don't have a copyright assignment on file. Would you > like to start the paperwork to do that now, so that your future > contributions won't stall? > > My contributions are covered by the agreement between Google and the FSF. Thanks, I didn't know that. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-17 8:26 ` Steinar Bang 2015-11-17 11:08 ` Aurélien Aptel @ 2015-11-17 17:10 ` John Wiegley 2015-11-18 0:17 ` Xue Fuqiao 1 sibling, 1 reply; 765+ messages in thread From: John Wiegley @ 2015-11-17 17:10 UTC (permalink / raw) To: emacs-devel >>>>> Steinar Bang <sb@dod.no> writes: > Hm... wasn't dynamic loading intended as an emacs 25 feature? I'd like for this to be an emacs 25 feature, unless it still has lots of implementation work left; then it should go into master toward 25.2. Criteria for 25.1 now is: Bug fixes and work that refines/improves code already in 25.1. No new functionality, or anything that would destabilize 25.1. In particular, no API changes of any kind without discussion. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-17 17:10 ` John Wiegley @ 2015-11-18 0:17 ` Xue Fuqiao 2015-11-18 1:20 ` Xue Fuqiao 0 siblings, 1 reply; 765+ messages in thread From: Xue Fuqiao @ 2015-11-18 0:17 UTC (permalink / raw) To: Emacs-devel On Wed, Nov 18, 2015 at 1:10 AM, John Wiegley <jwiegley@gmail.com> wrote: >>>>>> Steinar Bang <sb@dod.no> writes: > >> Hm... wasn't dynamic loading intended as an emacs 25 feature? > > I'd like for this to be an emacs 25 feature, unless it still has lots of > implementation work left; then it should go into master toward 25.2. 25.2 should be a bugfix release. See admin/notes/versioning. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-18 0:17 ` Xue Fuqiao @ 2015-11-18 1:20 ` Xue Fuqiao 2015-11-18 3:08 ` John Wiegley 0 siblings, 1 reply; 765+ messages in thread From: Xue Fuqiao @ 2015-11-18 1:20 UTC (permalink / raw) To: Emacs-devel On Wed, Nov 18, 2015 at 8:17 AM, Xue Fuqiao <xfq.free@gmail.com> wrote: > On Wed, Nov 18, 2015 at 1:10 AM, John Wiegley <jwiegley@gmail.com> wrote: >>>>>>> Steinar Bang <sb@dod.no> writes: >> >>> Hm... wasn't dynamic loading intended as an emacs 25 feature? >> >> I'd like for this to be an emacs 25 feature, unless it still has lots of >> implementation work left; then it should go into master toward 25.2. > > 25.2 should be a bugfix release. See admin/notes/versioning. But the current master is 25.1.50, instead of 26.0.50. And it accepts new features. Do you plan to change the versioning scheme (again), John? Ref: https://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00872.html ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-18 1:20 ` Xue Fuqiao @ 2015-11-18 3:08 ` John Wiegley 0 siblings, 0 replies; 765+ messages in thread From: John Wiegley @ 2015-11-18 3:08 UTC (permalink / raw) To: Xue Fuqiao; +Cc: Emacs-devel >>>>> Xue Fuqiao <xfq.free@gmail.com> writes: > But the current master is 25.1.50, instead of 26.0.50. And it accepts new > features. > Do you plan to change the versioning scheme (again), John? > Ref: https://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00872.html To me, version numbers are about delivery to the user. If APIs change, or Emacs start to look and feel different, it should be a major version bump. If it instead integrates something that's not really a user-facing feature, that can go in on a minor bump. In general, the 25 "series" should feel like a consistent march of refinement. Concurrency would very much justify 26.x, but I don't think dynamic loading should. That's much more of a developer-oriented feature. It doesn't change the overall feel, and while it adds APIs, it doesn't change them. (If I'm wrong on that last point, then yes, 26 it is). John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-09 10:40 ` Aurélien Aptel ` (2 preceding siblings ...) 2015-11-09 11:46 ` Ted Zlatanov @ 2015-11-09 13:16 ` Steinar Bang 2015-11-10 9:35 ` Suggestion to enable git rerere by default Nicolas Richard 4 siblings, 0 replies; 765+ messages in thread From: Steinar Bang @ 2015-11-09 13:16 UTC (permalink / raw) To: emacs-devel >>>>> Aurélien Aptel <aurelien.aptel+emacs@gmail.com>: > I already merged master in my branch at some point, and did so with > `merge --squash` IIRC, note to self: never do that again. Indeed. What this did was replace the master history merged into your branch with a single commit containing the diffs. This resulted in files with the same content, but with a broken history. The way I would have fixed this, would have been - make a copy of the current branch - roll back the branch to the commit just before the squash merge - do a regular merge with emacs master - cherry pick all commits made to the original branch after the squash merge After this I would have had a branch with identical contents, but that can be merged without problems to emacs master. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Suggestion to enable git rerere by default 2015-11-09 10:40 ` Aurélien Aptel ` (3 preceding siblings ...) 2015-11-09 13:16 ` Steinar Bang @ 2015-11-10 9:35 ` Nicolas Richard 2015-11-10 11:12 ` Artur Malabarba 4 siblings, 1 reply; 765+ messages in thread From: Nicolas Richard @ 2015-11-10 9:35 UTC (permalink / raw) To: Aurélien Aptel; +Cc: Emacs development discussions Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: > On Sun, Nov 8, 2015 at 9:38 PM, Ted Zlatanov <tzz@lifelogs.com> wrote: >>>> Agreed. Aurélien, the diff is huge and there are many conflicts. It >>>> looks like the fork from master happened in February 2015 and you're >>>> simply out of date. Can you please rebase against the emacs.git >>>> origin/master? Last push... > > I already merged master in my branch at some point, and did so with > `merge --squash` IIRC, note to self: never do that again. I agree with that conclusion. However I want to mention... > made any subsequent master merge a lot harder, sorry for that. The > weird thing is most conflicting changes where actually identical but > git couldn't tell. The diff were the same on both side but git couldnt > tell they were from the same commits since they were squashed. ...did you enable git rerere ? (you can check with: git config --get rerere.enabled). If not, I suggest that you do it: git config --global rerere.enabled 1 I'm not 100% sure that would have helped in your usecase, but it's useful anyway. Excerpt from `git help rerere' : In a workflow employing relatively long lived topic branches, the developer sometimes needs to resolve the same conflicts over and over again until the topic branches are done (either merged to the "release" branch, or sent out and accepted upstream). This command assists the developer in this process by recording conflicted automerge results and corresponding hand resolve results on the initial manual merge, and applying previously recorded hand resolutions to their corresponding automerge results. Perhaps we could add that as a suggestion in admin/notes/git-workflow : modified admin/notes/git-workflow @@ -124,6 +124,11 @@ the resulting merge, but if you really want to, feel free to do that. Note you can also resume gitmerge in a new Emacs session, since the current state will be saved to disk. +The following is helpful if you're going to merge the same set of +changes multiple times : + + git config --global rerere.enabled 1 + When everything's done, look hard at the resulting merge. Skipping commits requires separate merges, so don't be surprised to see more than one merge commit. If you're happy, push. -- Nicolas Richard ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Suggestion to enable git rerere by default 2015-11-10 9:35 ` Suggestion to enable git rerere by default Nicolas Richard @ 2015-11-10 11:12 ` Artur Malabarba 2015-11-10 13:01 ` Nicolas Richard 0 siblings, 1 reply; 765+ messages in thread From: Artur Malabarba @ 2015-11-10 11:12 UTC (permalink / raw) To: Nicolas Richard; +Cc: Aurélien Aptel, Emacs development discussions Nicolas Richard <youngfrog@members.fsf.org> writes: > Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: >> made any subsequent master merge a lot harder, sorry for that. The >> weird thing is most conflicting changes where actually identical but >> git couldn't tell. The diff were the same on both side but git couldnt >> tell they were from the same commits since they were squashed. > > ...did you enable git rerere ? (you can check with: git config --get > rerere.enabled). If not, I suggest that you do it: > git config --global rerere.enabled 1 I had never heard about it. If it's really as nice as it sounds (no drawbacks?), lets add this recommendation. > modified admin/notes/git-workflow > @@ -124,6 +124,11 @@ the resulting merge, but if you really want to, feel free to do that. > Note you can also resume gitmerge in a new Emacs session, since the > current state will be saved to disk. > > +The following is helpful if you're going to merge the same set of > +changes multiple times : This sounds strange to me. Would it be better to say: “if you're going to merge master onto the same (long-lived) feature branch multiple times”? ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Suggestion to enable git rerere by default 2015-11-10 11:12 ` Artur Malabarba @ 2015-11-10 13:01 ` Nicolas Richard 0 siblings, 0 replies; 765+ messages in thread From: Nicolas Richard @ 2015-11-10 13:01 UTC (permalink / raw) To: Artur Malabarba; +Cc: Aurélien Aptel, Emacs development discussions > I had never heard about it. If it's really as nice as it sounds (no > drawbacks?), lets add this recommendation. Here's what I found on the potential drawbacks: http://stackoverflow.com/questions/5519244/are-there-any-downsides-to-enabling-git-rerere IIUC the main problem is rerere might resolve conflicts that textually look the same but were semantically different Note that when rerere does its work, it leaves no conflict markers but the changes are still left uncommitted and you can review them. > > +The following is helpful if you're going to merge the same set of > > +changes multiple times : > This sounds strange to me. Would it be better to say: “if you're going > to merge master onto the same (long-lived) feature branch multiple > times”? I'll trust you. I'm 100% not english native. Nicolas ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-07 14:01 ` Ted Zlatanov 2015-11-07 17:47 ` Aurélien Aptel @ 2015-11-09 22:10 ` John Wiegley 2015-11-10 1:40 ` Ted Zlatanov 1 sibling, 1 reply; 765+ messages in thread From: John Wiegley @ 2015-11-09 22:10 UTC (permalink / raw) To: emacs-devel >>>>> Ted Zlatanov <tzz@lifelogs.com> writes: > I think 1 week is the time to feature freeze, but we have lots of time to > fix bugs and issues. Changing the module ABI/API for instance is IMHO > perfectly OK during the feature freeze. The feature is "dynamic modules" not > a specific version thereof, until Emacs is released. Then it becomes > "dynamic modules as defined by 25.1" and we have to live with them :) The feature freeze is just to draw a line between what will and won't be in 25 for sure. If you think this feature still deserves a lot of attention, though, it should go into master after we've released 25.1. John ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-09 22:10 ` Dynamic loading progress John Wiegley @ 2015-11-10 1:40 ` Ted Zlatanov 0 siblings, 0 replies; 765+ messages in thread From: Ted Zlatanov @ 2015-11-10 1:40 UTC (permalink / raw) To: emacs-devel On Mon, 09 Nov 2015 14:10:39 -0800 John Wiegley <jwiegley@gmail.com> wrote: >>>>>> Ted Zlatanov <tzz@lifelogs.com> writes: >> I think 1 week is the time to feature freeze, but we have lots of time to >> fix bugs and issues. Changing the module ABI/API for instance is IMHO >> perfectly OK during the feature freeze. The feature is "dynamic modules" not >> a specific version thereof, until Emacs is released. Then it becomes >> "dynamic modules as defined by 25.1" and we have to live with them :) JW> The feature freeze is just to draw a line between what will and won't be in 25 JW> for sure. If you think this feature still deserves a lot of attention, though, JW> it should go into master after we've released 25.1. Based on the discussions and code I think it's solid enough to be the "25.1 dynamic modules interface and implementation." Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-06 21:52 ` Dynamic loading progress John Wiegley 2015-11-07 8:35 ` Eli Zaretskii @ 2015-11-08 11:02 ` Philipp Stephani 2015-11-08 12:51 ` Steinar Bang 1 sibling, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-11-08 11:02 UTC (permalink / raw) To: emacs-devel [-- Attachment #1: Type: text/plain, Size: 739 bytes --] John Wiegley <jwiegley@gmail.com> schrieb am Sa., 7. Nov. 2015 um 05:58 Uhr: > >>>>> Ted Zlatanov <tzz@lifelogs.com> writes: > > > I've tried to review the discussion so far and believe the code is > > "functional enough." I think we got agreement from Stefan (probably John > > too) to exempt dynamic modules from the feature freeze. > > If Eli and Stefan agree, Stefan disagreed with (a) error handling (longjmp vs. local return) and (b) local object allocation (direct cast vs. a simple local allocator). > you have my go ahead to integrate the code. Would you prefer this as one big patch, or as several smaller ones? A big patch would make it easier to see the code in context, but splitting it up might increase review speed. [-- Attachment #2: Type: text/html, Size: 1274 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-08 11:02 ` Philipp Stephani @ 2015-11-08 12:51 ` Steinar Bang 2015-11-08 13:35 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Steinar Bang @ 2015-11-08 12:51 UTC (permalink / raw) To: emacs-devel >>>>> Philipp Stephani <p.stephani2@gmail.com>: > Would you prefer this as one big patch, or as several smaller ones? A big > patch would make it easier to see the code in context, but splitting it up > might increase review speed. Unless you have done strange rebasing on your git branch, but instead used plain merges, then I would suggest doing a git merge instead of using patches. That will preserve the full history of the files, for "git blame" (aka. annotate) and git log. The merge commit can also be used to provide the patch diff it that is desired for review, etc. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-11-08 12:51 ` Steinar Bang @ 2015-11-08 13:35 ` Philipp Stephani 0 siblings, 0 replies; 765+ messages in thread From: Philipp Stephani @ 2015-11-08 13:35 UTC (permalink / raw) To: emacs-devel [-- Attachment #1: Type: text/plain, Size: 614 bytes --] Steinar Bang <sb@dod.no> schrieb am So., 8. Nov. 2015 um 13:51 Uhr: > >>>>> Philipp Stephani <p.stephani2@gmail.com>: > > > Would you prefer this as one big patch, or as several smaller ones? A big > > patch would make it easier to see the code in context, but splitting it > up > > might increase review speed. > > Unless you have done strange rebasing on your git branch, but instead > used plain merges, then I would suggest doing a git merge instead of > using patches. > Fine with me, though that will likely produce lots of 'noise' commits because we weren't particularly strict about history cleanliness. [-- Attachment #2: Type: text/html, Size: 1000 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-04 19:34 ` Daniel Colascione 2015-10-04 19:47 ` Philipp Stephani @ 2015-10-14 22:34 ` Philipp Stephani 2015-10-14 22:38 ` Daniel Colascione 1 sibling, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-10-14 22:34 UTC (permalink / raw) To: Daniel Colascione, Eli Zaretskii Cc: Aurélien Aptel, stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1829 bytes --] Daniel Colascione <dancol@dancol.org> schrieb am So., 4. Okt. 2015 um 21:34 Uhr: > On 10/04/2015 02:41 AM, Philipp Stephani wrote: > > > > > > > > > typedef struct emacs_value_tag* emacs_value; > > > > > > > > > I think it's important that this is a pointer to a struct (for type > > > safety and size correctness) rather than just an arbitrary type. > > > > A typedef is exactly as typesafe. The question of whether to use a > > struct or a typedef is aesthetic. I strongly prefer a typedef, just > like > > pthreads, and I believe that the people who advocate using structs > > directly are simply wrong. > > > > > > Ah, I'm not against the typedef, I'm just asking whether you would make > > it part of the API contract that it's a typedef of a struct pointer, or > > whether it can be any type. > > The problem with defining it as a pointer type is that NULL is now the > invalid sentinel value, which seems incompatible with both making this > thing literally a Lisp_Object and Qnil having all zero bits. > > That's why I strongly prefer making emacs_value a _pointer_ to a > Lisp_Object, where we store the Lisp_Object in an array owned by the > emacs_env. This way, allocating local values is very cheap. > A simple fixed array however puts a fixed upper bound on the number of local values used. That might be undesirable, especially for plugins dealing with large data structures. The simplest unbound allocation mechanism would use an array of emacs_value pointers (emacs_value **) stored in the environment object; the array itself and its elements would be allocated using malloc as usual, and the array would be grown using realloc. However, that requires lots of allocations (at least one per local object used) and could make a more complex allocator necessary. [-- Attachment #2: Type: text/html, Size: 2306 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-14 22:34 ` Philipp Stephani @ 2015-10-14 22:38 ` Daniel Colascione 2015-10-14 23:32 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Daniel Colascione @ 2015-10-14 22:38 UTC (permalink / raw) To: Philipp Stephani, Eli Zaretskii Cc: Aurélien Aptel, stephen_leake, emacs-devel [-- Attachment #1: Type: text/plain, Size: 2390 bytes --] On 10/14/2015 03:34 PM, Philipp Stephani wrote: > > > Daniel Colascione <dancol@dancol.org <mailto:dancol@dancol.org>> schrieb > am So., 4. Okt. 2015 um 21:34 Uhr: > > On 10/04/2015 02:41 AM, Philipp Stephani wrote: > > > > > > > > > typedef struct emacs_value_tag* emacs_value; > > > > > > > > > I think it's important that this is a pointer to a struct > (for type > > > safety and size correctness) rather than just an arbitrary type. > > > > A typedef is exactly as typesafe. The question of whether to use a > > struct or a typedef is aesthetic. I strongly prefer a typedef, > just like > > pthreads, and I believe that the people who advocate using structs > > directly are simply wrong. > > > > > > Ah, I'm not against the typedef, I'm just asking whether you would > make > > it part of the API contract that it's a typedef of a struct > pointer, or > > whether it can be any type. > > The problem with defining it as a pointer type is that NULL is now the > invalid sentinel value, which seems incompatible with both making this > thing literally a Lisp_Object and Qnil having all zero bits. > > That's why I strongly prefer making emacs_value a _pointer_ to a > Lisp_Object, where we store the Lisp_Object in an array owned by the > emacs_env. This way, allocating local values is very cheap. > > > A simple fixed array however puts a fixed upper bound on the number of > local values used. That might be undesirable, especially for plugins > dealing with large data structures. Right. That's why we have multiple such arrays, each of a pretty decent size, linked together. Something like this: struct emacs_value_frame { Lisp_Object objects[512]; struct emacs_value_frame* next; }; struct emacs_env_guts { ... struct emacs_value_frame initial_frame; struct emacs_value_frame* current_frame; }; We get 512 local references for free just as a side effect of having an emacs_env, and if we need more references, we can heap-allocate another emacs_value_frame and make it current. This way, a reasonable number of local references is free, but if you need more, you can have them. This is exactly the approach Java uses. [-- Attachment #2: OpenPGP digital signature --] [-- Type: application/pgp-signature, Size: 819 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-14 22:38 ` Daniel Colascione @ 2015-10-14 23:32 ` Aurélien Aptel 2015-10-15 1:05 ` Philipp Stephani 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-10-14 23:32 UTC (permalink / raw) To: Daniel Colascione Cc: Philipp Stephani, Stephen Leake, Eli Zaretskii, Emacs development discussions Your approach is interesting but it currently works as-is for 64bits platforms and 32bits platform without wide-int and can be fixed later without breaking the API, if I understand correctly. I would rather focus on the remaining blocking things for the merge in master (and availability in Emacs 25!): * New opaque Lisp type to embbed C pointers with a vtable (for at least a finalizer) Can we re-use the finalizer feature you implemented? I haven't looked into it. * Loading I'm currently in the process of having `load' look for modules. For this I've added the system shared lib extension (.dll, .so, ...) to Vload_prefixes choosen at configure time (modules are not handled in Fload at the moment). I know that on OSX there's both ".dyn" and ".so" but I don't know much about it. Is supporting both worth it? Couldn't we simply pick an extension like ".edm" (emacs dynamic module) and rename the generated lib on each system when a module is built? * Doc strings If we use the doxygen syntax, it won't follow the various elisp conventions (args in caps, first line must be descriptive, etc). Jumping to definition is also pretty convenient, should we keep that feature for modules? Also how should we load the docstrings themselves? * Packaging We need to extend the spec of ELisp packages to take into account modules. The way I see it a module will have a "core" source file in C (or something else) and a bunch of helpers implemented in elisp on top that expose the package features in a more user-friendly way. As for distribution, only packaging sources is easier. This is a pretty big undertaking but we could bundle a compiler on platforms that don't have one easily accessible (like Strawberry Perl on Windows that bundles mingw-w64). ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-14 23:32 ` Aurélien Aptel @ 2015-10-15 1:05 ` Philipp Stephani 2015-10-15 10:50 ` Aurélien Aptel 0 siblings, 1 reply; 765+ messages in thread From: Philipp Stephani @ 2015-10-15 1:05 UTC (permalink / raw) To: Aurélien Aptel, Daniel Colascione Cc: Eli Zaretskii, Stephen Leake, Emacs development discussions [-- Attachment #1: Type: text/plain, Size: 2340 bytes --] Aurélien Aptel <aurelien.aptel+emacs@gmail.com> schrieb am Do., 15. Okt. 2015 um 01:32 Uhr: > Your approach is interesting but it currently works as-is for 64bits > platforms and 32bits platform without wide-int and can be fixed later > without breaking the API, if I understand correctly. > I would be more worried about representation of nullptr. With casting nullptr can stand for a valid Lisp value, so that it's not possible to return invalid values, which is visible to the user. > * Loading > > I know that on OSX there's both ".dyn" and ".so" but I don't know much > about it. Is supporting both worth it? > According to http://stackoverflow.com/a/2339910/178761 there are two types: bundles and dynamic libraries. The differences were bigger in the past (only bundles could be loaded dynamically), but now they are mostly equivalent. Apparently .so and .bundle are usually used for bundles and .dylib for dynamic libraries, but e.g. your example modules compile as dynamic libraries with an .so extension and Emacs is totally happy. So supporting .so should be enough. > > Couldn't we simply pick an extension like ".edm" (emacs dynamic > module) and rename the generated lib on each system when a module is > built? > I'd prefer using the conventional extensions. A custom extension might confuse users and clash with existing meanings of that extension. > > * Doc strings > > If we use the doxygen syntax, it won't follow the various elisp > conventions (args in caps, first line must be descriptive, etc). > Jumping to definition is also pretty convenient, should we keep that > feature for modules? Also how should we load the docstrings > themselves? > > Can't modules already run the equivalent of (put 'module-func 'function-documentation "docstring") ? With that the basics should already be there. > * Packaging > > We need to extend the spec of ELisp packages to take into account > modules. The way I see it a module will have a "core" source file in C > (or something else) and a bunch of helpers implemented in elisp on top > that expose the package features in a more user-friendly way. > That is one option, but modules consisting entirely of non-Elisp files are also to be expected, given that the module API is as powerful as Elisp. [-- Attachment #2: Type: text/html, Size: 3421 bytes --] ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 1:05 ` Philipp Stephani @ 2015-10-15 10:50 ` Aurélien Aptel 2015-10-15 19:25 ` Stephen Leake 0 siblings, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-10-15 10:50 UTC (permalink / raw) To: Philipp Stephani Cc: Eli Zaretskii, Daniel Colascione, Stephen Leake, Emacs development discussions On Thu, Oct 15, 2015 at 3:05 AM, Philipp Stephani <p.stephani2@gmail.com> wrote: > According to http://stackoverflow.com/a/2339910/178761 there are two types: > bundles and dynamic libraries. The differences were bigger in the past (only > bundles could be loaded dynamically), but now they are mostly equivalent. > Apparently .so and .bundle are usually used for bundles and .dylib for > dynamic libraries, but e.g. your example modules compile as dynamic > libraries with an .so extension and Emacs is totally happy. So supporting > .so should be enough. OK. > I'd prefer using the conventional extensions. A custom extension might > confuse users and clash with existing meanings of that extension. Fair enough. > (put 'module-func 'function-documentation "docstring") > > ? With that the basics should already be there. True, but we lose the jump-to-definition feature. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-10-15 10:50 ` Aurélien Aptel @ 2015-10-15 19:25 ` Stephen Leake 0 siblings, 0 replies; 765+ messages in thread From: Stephen Leake @ 2015-10-15 19:25 UTC (permalink / raw) To: Aurélien Aptel Cc: Philipp Stephani, Daniel Colascione, Eli Zaretskii, Emacs development discussions Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: > On Thu, Oct 15, 2015 at 3:05 AM, Philipp Stephani <p.stephani2@gmail.com> wrote: >> According to http://stackoverflow.com/a/2339910/178761 there are two types: >> bundles and dynamic libraries. The differences were bigger in the past (only >> bundles could be loaded dynamically), but now they are mostly equivalent. >> Apparently .so and .bundle are usually used for bundles and .dylib for >> dynamic libraries, but e.g. your example modules compile as dynamic >> libraries with an .so extension and Emacs is totally happy. So supporting >> .so should be enough. > > OK. > >> I'd prefer using the conventional extensions. A custom extension might >> confuse users and clash with existing meanings of that extension. > > Fair enough. > >> (put 'module-func 'function-documentation "docstring") >> >> ? With that the basics should already be there. > > True, but we lose the jump-to-definition feature. "jump-to-definition" relies on `load-history' (see elisp-mode.el elisp--xref-find-definitions and subr.el symbol-file). So module initialization functions can add the appropriate entries in `load-history'. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-15 17:31 ` Daniel Colascione 2015-02-15 18:00 ` Eli Zaretskii @ 2015-02-15 18:24 ` Andreas Schwab 1 sibling, 0 replies; 765+ messages in thread From: Andreas Schwab @ 2015-02-15 18:24 UTC (permalink / raw) To: Daniel Colascione; +Cc: Eli Zaretskii, stephen_leake, emacs-devel Daniel Colascione <dancol@dancol.org> writes: > Positionally, as fixed in the structure that defines the table. > > struct { > void (*func1)(int); > void (*func2)(double); > /* etc. */ > } > > This way, the ABI Emacs exports is explicit, and breaking it is unlikely > to happen accidentally. You should allow for future extension, by adding a version field. Andreas. -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5 "And now for something completely different." ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-14 15:13 ` Stephen Leake 2015-02-14 15:51 ` Eli Zaretskii @ 2015-02-15 18:39 ` Stefan Monnier 1 sibling, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2015-02-15 18:39 UTC (permalink / raw) To: Stephen Leake; +Cc: emacs-devel >> If that doesn't work, then we really need an emacs.h file ASAP, and >> the module should include only that file, without including <config.h> >> inside that file. > Nor <lisp.h>. And probably not lots of other things. Of course not. It's the other way around: lisp.h should include emacs.h. > Is there an acceptable (ie portable and reliable) way to determine the > OS in a Makefile? I'm not aware of one (short of Gnu config.guess). M-x module-make RET should do the trick, since Emacs knows for which OS it was built and can know which compiler options were used. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-11 21:17 ` Ted Zlatanov 2015-02-12 0:22 ` Aurélien Aptel 2015-02-12 10:51 ` Stephen Leake @ 2015-02-12 21:39 ` Aurélien Aptel 2 siblings, 0 replies; 765+ messages in thread From: Aurélien Aptel @ 2015-02-12 21:39 UTC (permalink / raw) To: Emacs development discussions On Wed, Feb 11, 2015 at 10:17 PM, Ted Zlatanov <tzz@lifelogs.com> wrote: >>> Symbol's function definition is void: defun > [*] running test.el... > Eager macro-expansion failure: (void-variable ) > Running 5 tests (2015-02-11 16:13:26-0500) > /home/tzz/source/emacs/emacs/src/emacs: symbol lookup error: /home/tzz/source/emacs/emacs/modules/yaml/yaml.so: undefined symbol: yaml_parser_initialize The branch builds fine on my machine (archlinux), both with and without ltdl configure options. There is something wrong the linker/linking parameters for the emacs binary or modules. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-11 16:24 ` Aurélien Aptel 2015-02-11 21:17 ` Ted Zlatanov @ 2015-02-13 21:29 ` Stephen Leake 1 sibling, 0 replies; 765+ messages in thread From: Stephen Leake @ 2015-02-13 21:29 UTC (permalink / raw) To: emacs-devel Aurélien Aptel <aurelien.aptel+emacs@gmail.com> writes: > Run ./modules/tests.py. It should work no matter the current working > directory. This works for me in branch feature/aptel/dynamic-modules-rc3 on Debian stable (wheezy) 32 bit. -- -- Stephe ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-01-31 18:57 ` Aurélien Aptel 2015-01-31 19:30 ` Eli Zaretskii @ 2015-02-04 12:11 ` Ted Zlatanov 2015-02-04 15:22 ` Stefan Monnier 2015-02-04 21:49 ` Aurélien Aptel 1 sibling, 2 replies; 765+ messages in thread From: Ted Zlatanov @ 2015-02-04 12:11 UTC (permalink / raw) To: emacs-devel On Sat, 31 Jan 2015 19:57:42 +0100 Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: AA> I'm just letting everyone know I'm working on my patch again. I've AA> started by merging the last 2-3 months commits in master but of course AA> there are merge conflicts... It's taking more time to resolve than AA> anticipated. AA> There's a macro conflict with "Qc". I had to rename Qc to Qc_ in AA> modules/opaque/opaque.c because globals.h defines Qc to something. AA> I'm also working on a small test suite since I (and maintainers) AA> quickly want to know when my code breaks. Great, thanks. I assume you started with the dynamic-modules-rc2 branch I pushed to the Emacs repo? If not, take a look at it. With the test suite, I'm sure we'll be able to merge it very quickly. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-04 12:11 ` Ted Zlatanov @ 2015-02-04 15:22 ` Stefan Monnier 2015-02-04 21:49 ` Aurélien Aptel 1 sibling, 0 replies; 765+ messages in thread From: Stefan Monnier @ 2015-02-04 15:22 UTC (permalink / raw) To: emacs-devel AA> I'm just letting everyone know I'm working on my patch again. I've AA> started by merging the last 2-3 months commits in master but of course AA> there are merge conflicts... It's taking more time to resolve than AA> anticipated. If you're not sure what to do with a particular conflict, you can sent it here: it's likely that someone will be able to tell you very quickly what's up with it. Most conflicts are "trivial" to solve to those who know what was the reason for the change. Stefan ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-04 12:11 ` Ted Zlatanov 2015-02-04 15:22 ` Stefan Monnier @ 2015-02-04 21:49 ` Aurélien Aptel 2015-02-04 23:00 ` Ted Zlatanov 1 sibling, 1 reply; 765+ messages in thread From: Aurélien Aptel @ 2015-02-04 21:49 UTC (permalink / raw) To: Emacs development discussions On Wed, Feb 4, 2015 at 1:11 PM, Ted Zlatanov <tzz@lifelogs.com> wrote: > On Sat, 31 Jan 2015 19:57:42 +0100 Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: > > AA> I'm just letting everyone know I'm working on my patch again. I've > AA> started by merging the last 2-3 months commits in master but of course > AA> there are merge conflicts... It's taking more time to resolve than > AA> anticipated. > > AA> There's a macro conflict with "Qc". I had to rename Qc to Qc_ in > AA> modules/opaque/opaque.c because globals.h defines Qc to something. > > AA> I'm also working on a small test suite since I (and maintainers) > AA> quickly want to know when my code breaks. > > Great, thanks. I assume you started with the dynamic-modules-rc2 branch > I pushed to the Emacs repo? If not, take a look at it. Nope, I've used my dynamic-modules branch... fuck. Someone keeps messing with small parts of doc.c I'm also working on and each time I have to re-understand partially how the spaghetti code in Snarf_documention works to merge. Currently, the wrong prefix (sibling_xxx) is added to the doc file path which prevent the docstring to be loaded and makes emacs abort. I'm sure it's not hard but it's the third time and it tires me. I should have waited to merge or let someone else do it. Sorry for the rant. I've tried to keep every changes from master while merging, I hope I haven't skipped/reverted something. > With the test suite, I'm sure we'll be able to merge it very quickly. I've made some tests in several module test.el file using ERT. There's algo a small script in modules/tests.py which runs all the module tests. Be warned though, since the loading part is broken I've written the tests blindly. Some might fail/pass when they should/nt. The code is on my dynamic-modules branch on my github repo. $ git clone https://github.com/aaptel/emacs-dynamic-module.git $ git checkout dynamic-modules I'm sure there's a lighter way to get it (if you already have the emacs repo) involving arcane git commands. If you know them I'm interested. ^ permalink raw reply [flat|nested] 765+ messages in thread
* Re: Dynamic loading progress 2015-02-04 21:49 ` Aurélien Aptel @ 2015-02-04 23:00 ` Ted Zlatanov 0 siblings, 0 replies; 765+ messages in thread From: Ted Zlatanov @ 2015-02-04 23:00 UTC (permalink / raw) To: emacs-devel On Wed, 4 Feb 2015 22:49:44 +0100 Aurélien Aptel <aurelien.aptel+emacs@gmail.com> wrote: AA> Nope, I've used my dynamic-modules branch... fuck. Yeah, at this point my work has diverged too much from yours. My work was mostly adding ChangeLogs and cleaning up, so don't worry, just keep going with your side. AA> The code is on my dynamic-modules branch on my github repo. AA> $ git clone https://github.com/aaptel/emacs-dynamic-module.git AA> $ git checkout dynamic-modules AA> I'm sure there's a lighter way to get it (if you already have the AA> emacs repo) involving arcane git commands. If you know them I'm AA> interested. git fetch git@github.com:aaptel/emacs-dynamic-module.git dynamic-modules ... then work against FETCH_HEAD ... I pushed your work so far to the Emacs repo in branch feature/aptel/dynamic-modules-rc3 so: git clone emacs-repo-url git co feature/aptel/dynamic-modules-rc3 git log master.. shows your commits correctly. We can do a final cleanup with `git rebase -i master' and fix ChangeLogs, etc. but let's get it in a working state first. I'll delete the dynamic-modules-rc2 branch eventually but am leaving it for now in case I want the ChangeLog entries I wrote there. Ted ^ permalink raw reply [flat|nested] 765+ messages in thread
end of thread, other threads:[~2015-11-25 18:53 UTC | newest] Thread overview: 765+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-07-02 20:54 Dynamic loading progress Aurélien Aptel 2014-07-02 21:33 ` Andreas Schwab 2014-07-03 17:09 ` Aurélien Aptel 2014-07-03 17:43 ` Dmitry Antipov 2014-07-03 19:44 ` Stefan Monnier 2014-07-04 1:26 ` Stefan Monnier 2014-07-06 15:14 ` Aurélien Aptel 2014-07-07 1:19 ` Stefan Monnier 2014-07-09 21:02 ` Aurélien Aptel 2014-07-09 22:18 ` Stefan Monnier 2014-07-10 17:21 ` Aurélien Aptel 2014-07-10 18:04 ` Stefan Monnier 2014-07-11 9:01 ` Aurélien Aptel 2014-07-11 13:27 ` Stefan Monnier 2014-09-24 14:20 ` Ted Zlatanov 2014-09-24 17:27 ` Stefan Monnier 2014-09-25 12:41 ` Ted Zlatanov 2014-10-09 17:08 ` Aurélien Aptel 2014-10-09 17:11 ` Aurélien Aptel 2014-10-09 17:27 ` Eli Zaretskii 2014-10-09 19:42 ` Stefan Monnier 2014-10-09 21:17 ` Eli Zaretskii 2014-10-10 0:53 ` Stefan Monnier 2014-10-10 6:32 ` Eli Zaretskii 2014-10-10 12:54 ` Stefan Monnier 2014-10-10 15:05 ` Aurélien Aptel 2014-10-10 15:50 ` Eli Zaretskii 2014-10-10 18:42 ` Stefan Monnier 2014-10-10 19:58 ` Eli Zaretskii 2014-10-11 5:14 ` Stefan Monnier 2014-10-13 17:46 ` Aurélien Aptel 2014-10-14 18:11 ` Stefan Monnier 2014-10-16 23:09 ` Aurélien Aptel 2014-10-17 0:32 ` Stefan Monnier 2014-10-18 21:06 ` Stephen Leake 2014-12-27 21:57 ` Stephen Leake 2015-01-13 14:28 ` Ted Zlatanov 2015-01-13 15:39 ` Stephen Leake 2015-01-17 0:10 ` Stephen Leake 2015-01-31 18:57 ` Aurélien Aptel 2015-01-31 19:30 ` Eli Zaretskii 2015-02-04 21:58 ` Aurélien Aptel 2015-02-04 22:03 ` Aurélien Aptel 2015-02-05 0:24 ` Stephen J. Turnbull 2015-02-05 3:50 ` Eli Zaretskii 2015-02-09 0:04 ` Aurélien Aptel 2015-02-09 0:34 ` Paul Eggert 2015-02-09 4:17 ` Stefan Monnier 2015-02-09 6:26 ` Paul Eggert 2015-02-09 9:58 ` Aurélien Aptel 2015-02-09 15:45 ` Eli Zaretskii 2015-02-09 16:01 ` Aurélien Aptel 2015-02-10 6:58 ` Paul Eggert 2015-02-10 20:40 ` Stefan Monnier 2015-02-10 22:24 ` Paul Eggert 2015-02-11 1:45 ` Stefan Monnier 2015-02-11 15:36 ` Ted Zlatanov 2015-02-13 2:40 ` Paul Eggert 2015-02-13 8:37 ` Eli Zaretskii 2015-02-13 12:17 ` Daniel Colascione 2015-02-13 15:01 ` Eli Zaretskii 2015-02-13 15:06 ` Daniel Colascione 2015-02-13 15:49 ` Eli Zaretskii 2015-02-13 15:58 ` Daniel Colascione 2015-02-13 16:10 ` Eli Zaretskii 2015-02-13 16:20 ` Daniel Colascione 2015-02-13 16:55 ` Eli Zaretskii 2015-02-13 17:08 ` Paul Eggert 2015-02-13 17:44 ` Daniel Colascione 2015-02-13 19:11 ` Eli Zaretskii 2015-02-13 17:38 ` Daniel Colascione 2015-02-13 21:48 ` Stephen Leake 2015-02-14 8:39 ` Eli Zaretskii 2015-02-14 12:18 ` Stephen J. Turnbull 2015-02-14 12:37 ` Eli Zaretskii 2015-02-14 14:38 ` Stefan Monnier 2015-02-14 14:58 ` Eli Zaretskii 2015-02-15 18:36 ` Stefan Monnier 2015-02-15 18:55 ` Eli Zaretskii 2015-02-15 22:36 ` Stefan Monnier 2015-02-14 16:48 ` Stephen J. Turnbull 2015-02-14 17:22 ` Eli Zaretskii 2015-02-15 8:03 ` Stephen J. Turnbull 2015-02-15 12:46 ` Steinar Bang 2015-02-15 17:33 ` Eli Zaretskii 2015-02-15 18:47 ` Stefan Monnier 2015-02-15 19:00 ` Eli Zaretskii 2015-02-15 22:40 ` Stefan Monnier 2015-02-14 15:32 ` Stephen Leake 2015-02-14 16:02 ` Eli Zaretskii 2015-02-14 16:45 ` Eli Zaretskii 2015-02-15 0:39 ` Stephen Leake 2015-02-15 13:54 ` Daniel Colascione 2015-02-15 18:08 ` Stephen Leake 2015-02-15 18:43 ` Stefan Monnier 2015-02-15 18:56 ` Eli Zaretskii 2015-02-16 4:52 ` Stephen J. Turnbull 2015-02-16 13:44 ` Aurélien Aptel 2015-02-15 19:27 ` joakim 2015-02-15 22:39 ` Stefan Monnier 2015-02-16 13:53 ` joakim 2015-02-15 0:35 ` Stephen Leake 2015-02-13 19:11 ` Stefan Monnier 2015-02-14 19:12 ` Eli Zaretskii 2015-02-14 19:25 ` Eli Zaretskii 2015-02-15 1:02 ` Stephen Leake 2015-02-15 17:32 ` Eli Zaretskii 2015-02-15 19:09 ` Stephen Leake 2015-02-15 19:27 ` implementing curl module with opaque emacs types Stephen Leake 2015-02-15 19:47 ` Eli Zaretskii 2015-02-17 19:33 ` Stephen Leake 2015-02-15 19:28 ` Dynamic loading progress Eli Zaretskii 2015-02-15 19:30 ` Stefan Monnier 2015-02-16 15:25 ` Stephen Leake 2015-02-16 19:02 ` Stefan Monnier 2015-04-20 23:21 ` Ted Zlatanov 2015-04-21 14:06 ` Stefan Monnier 2015-04-21 14:19 ` Ted Zlatanov 2015-02-15 9:21 ` Stephen J. Turnbull 2015-02-15 17:34 ` Eli Zaretskii 2015-02-11 9:19 ` Aurélien Aptel 2015-02-11 9:43 ` Aurélien Aptel 2015-02-11 10:01 ` Aurélien Aptel 2015-02-11 15:35 ` Stefan Monnier 2015-02-11 16:08 ` Aurélien Aptel 2015-02-11 19:17 ` Stefan Monnier 2015-02-11 13:26 ` Paul Eggert 2015-02-10 14:56 ` Ted Zlatanov 2015-02-11 9:55 ` Aurélien Aptel 2015-02-11 16:05 ` Ted Zlatanov 2015-02-11 16:24 ` Aurélien Aptel 2015-02-11 21:17 ` Ted Zlatanov 2015-02-12 0:22 ` Aurélien Aptel 2015-02-12 10:07 ` Stephen Leake 2015-02-12 10:51 ` Stephen Leake 2015-02-12 18:02 ` Stephen Leake 2015-02-14 0:49 ` Davis Herring 2015-02-12 20:09 ` Stephen Leake 2015-02-12 20:34 ` Eli Zaretskii 2015-02-12 21:51 ` Aurélien Aptel 2015-02-12 21:55 ` Aurélien Aptel 2015-02-13 8:29 ` Eli Zaretskii 2015-02-13 19:09 ` Stefan Monnier 2015-02-13 8:27 ` Eli Zaretskii 2015-02-13 21:11 ` Stephen Leake 2015-02-13 21:09 ` Stephen Leake 2015-02-14 9:31 ` Eli Zaretskii 2015-02-14 15:13 ` Stephen Leake 2015-02-14 15:51 ` Eli Zaretskii 2015-02-15 1:04 ` Stephen Leake 2015-02-15 13:50 ` Daniel Colascione 2015-02-15 17:00 ` Eli Zaretskii 2015-02-15 17:04 ` Daniel Colascione 2015-02-15 17:28 ` Eli Zaretskii 2015-02-15 17:31 ` Daniel Colascione 2015-02-15 18:00 ` Eli Zaretskii 2015-02-15 18:01 ` Daniel Colascione 2015-02-15 18:29 ` Eli Zaretskii 2015-02-15 20:20 ` Daniel Colascione 2015-02-16 14:05 ` Aurélien Aptel 2015-02-16 16:15 ` Eli Zaretskii 2015-02-16 15:43 ` Eli Zaretskii 2015-02-16 18:22 ` Daniel Colascione 2015-02-16 19:09 ` Stefan Monnier 2015-02-16 19:29 ` Eli Zaretskii 2015-02-16 20:01 ` Daniel Colascione 2015-02-17 15:43 ` Eli Zaretskii 2015-02-17 17:46 ` Aurélien Aptel 2015-02-17 17:50 ` Aurélien Aptel 2015-02-17 18:04 ` Daniel Colascione 2015-02-18 3:29 ` Stefan Monnier 2015-02-28 18:20 ` Aurélien Aptel 2015-03-04 13:48 ` Stephen Leake 2015-03-04 22:34 ` Stefan Monnier 2015-03-04 22:39 ` Daniel Colascione 2015-03-05 13:12 ` Aurélien Aptel 2015-03-05 17:37 ` Paul Eggert 2015-03-05 18:19 ` Aurélien Aptel 2015-04-20 23:38 ` Ted Zlatanov 2015-04-21 8:58 ` Aurélien Aptel 2015-04-21 14:14 ` Ted Zlatanov 2015-04-22 16:25 ` Stephen Leake 2015-04-22 17:15 ` Stefan Monnier 2015-05-03 10:43 ` Ted Zlatanov 2015-05-03 10:55 ` Ted Zlatanov 2015-05-03 23:44 ` Stephen Leake 2015-05-04 10:09 ` Ted Zlatanov 2015-05-04 0:16 ` Stefan Monnier 2015-05-04 10:03 ` Ted Zlatanov 2015-08-19 14:27 ` Ted Zlatanov 2015-08-20 15:19 ` Stephen Leake 2015-08-23 19:12 ` Aurélien Aptel 2015-08-23 22:26 ` Stefan Monnier 2015-08-23 22:45 ` Aurélien Aptel 2015-08-23 23:37 ` Paul Eggert 2015-08-24 19:11 ` Stefan Monnier 2015-08-24 2:13 ` Tom Tromey 2015-08-24 19:13 ` Stefan Monnier 2015-08-24 20:19 ` Paul Eggert 2015-08-25 4:35 ` David Kastrup 2015-08-25 22:03 ` Stefan Monnier 2015-08-27 2:29 ` Paul Eggert 2015-08-27 10:17 ` Aurélien Aptel 2015-09-12 19:38 ` Aurélien Aptel 2015-09-12 20:42 ` Stefan Monnier 2015-09-12 23:11 ` Aurélien Aptel 2015-09-13 12:54 ` Philipp Stephani 2015-09-13 13:14 ` Stefan Monnier 2015-09-13 13:19 ` Philipp Stephani 2015-09-13 20:31 ` Stefan Monnier 2015-09-13 20:33 ` Daniel Colascione 2015-09-14 1:58 ` Stefan Monnier 2015-09-14 2:08 ` Daniel Colascione 2015-09-14 4:18 ` Stefan Monnier 2015-09-14 4:37 ` Daniel Colascione 2015-09-14 12:14 ` Stefan Monnier 2015-09-14 14:36 ` Stephen Leake 2015-09-14 15:17 ` Eli Zaretskii 2015-09-14 15:14 ` Daniel Colascione 2015-09-14 17:48 ` Stefan Monnier 2015-09-14 18:05 ` Daniel Colascione 2015-09-15 0:55 ` Stefan Monnier 2015-09-15 1:06 ` Daniel Colascione 2015-09-24 12:45 ` Aurélien Aptel 2015-09-24 13:58 ` Stefan Monnier 2015-09-26 14:56 ` Aurélien Aptel 2015-09-28 3:01 ` Stefan Monnier 2015-09-28 10:13 ` Aurélien Aptel 2015-09-28 21:59 ` Davis Herring 2015-09-28 15:57 ` Stephen Leake 2015-09-28 15:42 ` Philipp Stephani 2015-09-28 16:12 ` Aurélien Aptel 2015-09-28 19:39 ` Stefan Monnier 2015-09-28 19:41 ` Daniel Colascione 2015-09-29 5:04 ` Stefan Monnier 2015-10-04 4:30 ` Tom Tromey 2015-10-04 14:11 ` Aurélien Aptel 2015-10-04 14:22 ` Aurélien Aptel 2015-09-28 15:35 ` Philipp Stephani 2015-09-28 17:04 ` Philipp Stephani 2015-09-28 19:30 ` Stefan Monnier 2015-10-04 13:25 ` Aurélien Aptel 2015-10-04 14:38 ` Philipp Stephani 2015-09-28 15:25 ` Philipp Stephani 2015-09-28 19:26 ` Stefan Monnier 2015-09-28 19:31 ` Daniel Colascione 2015-09-28 19:28 ` Daniel Colascione 2015-09-28 20:09 ` Philipp Stephani 2015-09-28 20:10 ` Daniel Colascione 2015-09-29 5:00 ` Stefan Monnier 2015-09-15 2:56 ` Stephen J. Turnbull 2015-09-15 3:00 ` Daniel Colascione 2015-09-15 8:16 ` Stephen J. Turnbull 2015-09-15 8:45 ` David Kastrup 2015-09-15 13:18 ` Daniel Colascione 2015-09-15 13:33 ` David Kastrup 2015-09-15 13:39 ` Daniel Colascione 2015-09-15 13:43 ` David Kastrup 2015-09-15 16:11 ` Stephen J. Turnbull 2015-09-15 7:45 ` Michael Albinus 2015-09-28 15:12 ` Philipp Stephani 2015-09-28 19:20 ` Stefan Monnier 2015-09-14 3:43 ` Stephen J. Turnbull 2015-09-14 3:54 ` Daniel Colascione 2015-09-14 4:24 ` Stefan Monnier 2015-09-28 15:21 ` Philipp Stephani 2015-09-28 19:23 ` Stefan Monnier 2015-09-14 7:27 ` Stephen J. Turnbull 2015-09-14 14:45 ` Stephen Leake 2015-09-15 1:46 ` Stephen J. Turnbull 2015-09-28 15:19 ` Philipp Stephani 2015-09-29 1:55 ` Stephen J. Turnbull 2015-09-29 9:11 ` David Kastrup 2015-09-30 6:06 ` Stephen J. Turnbull 2015-09-30 6:24 ` David Kastrup 2015-09-29 21:04 ` Davis Herring 2015-09-30 6:07 ` Stephen J. Turnbull 2015-09-30 6:56 ` Herring, Davis 2015-09-30 7:26 ` Daniel Colascione 2015-09-30 8:52 ` Stefan Monnier 2015-10-04 8:34 ` Philipp Stephani 2015-10-04 17:24 ` Stefan Monnier 2015-09-30 17:16 ` Stephen J. Turnbull 2015-09-30 17:32 ` Davis Herring 2015-03-05 13:17 ` Aurélien Aptel 2015-03-06 5:14 ` Stefan Monnier 2015-03-06 18:22 ` Daniel Colascione 2015-03-10 1:26 ` Stefan Monnier 2015-03-05 17:19 ` Stephen Leake 2015-03-05 22:32 ` Stephen Leake 2015-03-13 16:47 ` Stephen Leake 2015-03-13 18:37 ` Ivan Shmakov 2015-03-15 10:46 ` Stephen Leake 2015-03-16 18:02 ` Stephen Leake 2015-03-17 9:28 ` Aurélien Aptel 2015-03-17 9:52 ` Eli Zaretskii 2015-03-17 10:51 ` Aurélien Aptel 2015-03-17 11:08 ` Eli Zaretskii 2015-03-17 16:37 ` Stefan Monnier 2015-03-17 17:08 ` Eli Zaretskii 2015-03-17 14:50 ` Stephen Leake 2015-03-24 21:08 ` Stephen Leake 2015-05-06 4:11 ` Dynamic loading progress; funcall of goto-char fails Stephen Leake 2015-05-06 4:21 ` Daniel Colascione 2015-05-06 8:15 ` Stephen Leake 2015-02-17 18:06 ` Dynamic loading progress Eli Zaretskii 2015-02-17 18:20 ` Steinar Bang 2015-02-18 0:55 ` Stephen J. Turnbull 2015-09-13 13:04 ` Philipp Stephani 2015-09-13 14:15 ` Daniel Colascione 2015-09-13 14:27 ` Philipp Stephani 2015-09-13 14:31 ` Daniel Colascione 2015-09-28 15:05 ` Philipp Stephani 2015-10-04 8:57 ` Philipp Stephani 2015-10-04 9:00 ` Eli Zaretskii 2015-10-04 9:10 ` Daniel Colascione 2015-10-04 9:41 ` Philipp Stephani 2015-10-04 17:48 ` Philipp Stephani 2015-10-04 19:20 ` Paul Eggert 2015-10-04 19:25 ` Daniel Colascione 2015-10-04 19:55 ` Paul Eggert 2015-10-04 19:57 ` Daniel Colascione 2015-10-04 20:19 ` Paul Eggert 2015-10-04 19:34 ` Daniel Colascione 2015-10-04 19:47 ` Philipp Stephani 2015-10-04 21:12 ` Aurélien Aptel 2015-10-05 5:50 ` Eli Zaretskii 2015-10-14 22:28 ` Philipp Stephani 2015-10-15 2:43 ` Eli Zaretskii 2015-10-15 7:00 ` Andreas Schwab 2015-10-15 10:13 ` Aurélien Aptel 2015-10-15 15:38 ` Eli Zaretskii 2015-10-15 15:56 ` Andreas Schwab 2015-10-15 16:01 ` Eli Zaretskii 2015-10-15 16:07 ` Andreas Schwab 2015-10-15 16:31 ` Eli Zaretskii 2015-10-15 17:03 ` Andreas Schwab 2015-10-15 17:07 ` Eli Zaretskii 2015-10-15 23:07 ` Philipp Stephani 2015-10-16 6:49 ` Eli Zaretskii 2015-10-14 22:25 ` Philipp Stephani 2015-10-14 23:48 ` Aurélien Aptel 2015-10-15 0:25 ` Philipp Stephani 2015-10-15 10:44 ` Aurélien Aptel 2015-10-15 15:41 ` Eli Zaretskii 2015-10-16 0:55 ` Juanma Barranquero 2015-10-16 5:42 ` martin rudalics 2015-10-16 7:10 ` Making --with-wide-int the default (was: Dynamic loading progress) Eli Zaretskii 2015-10-16 7:34 ` Making --with-wide-int the default martin rudalics 2015-10-16 8:10 ` Eli Zaretskii 2015-10-16 7:09 ` Making --with-wide-int the default (was: Dynamic loading progress) Eli Zaretskii 2015-10-16 7:26 ` Juanma Barranquero 2015-10-16 8:17 ` Eli Zaretskii 2015-10-16 8:03 ` Making --with-wide-int the default Paul Eggert 2015-10-16 8:15 ` Eli Zaretskii 2015-10-16 8:27 ` Paul Eggert 2015-10-16 8:31 ` David Kastrup 2015-10-16 9:12 ` Eli Zaretskii 2015-10-16 9:24 ` David Kastrup 2015-10-16 9:26 ` David Kastrup 2015-10-16 10:12 ` Eli Zaretskii 2015-10-16 10:28 ` David Kastrup 2015-10-16 13:22 ` Eli Zaretskii 2015-10-16 15:29 ` Paul Eggert 2015-11-11 18:43 ` Eli Zaretskii 2015-11-12 8:23 ` martin rudalics 2015-11-12 16:19 ` Eli Zaretskii 2015-11-12 18:00 ` martin rudalics 2015-11-12 22:31 ` Richard Stallman 2015-11-13 7:43 ` Eli Zaretskii 2015-11-13 7:52 ` Paul Eggert 2015-11-13 8:05 ` martin rudalics 2015-11-13 8:24 ` Eli Zaretskii 2015-11-13 9:11 ` David Kastrup 2015-11-13 9:30 ` Eli Zaretskii 2015-11-13 11:52 ` David Kastrup 2015-11-13 18:56 ` Eli Zaretskii 2015-11-13 22:03 ` Richard Stallman 2015-11-14 8:43 ` Eli Zaretskii 2015-11-14 8:54 ` martin rudalics 2015-11-14 17:38 ` Ulrich Mueller 2015-11-15 20:14 ` Eli Zaretskii 2015-11-15 20:50 ` David Kastrup 2015-11-15 21:06 ` Eli Zaretskii 2015-11-15 22:19 ` David Kastrup 2015-11-16 16:38 ` Eli Zaretskii 2015-11-15 21:04 ` Ulrich Mueller 2015-11-15 21:13 ` Eli Zaretskii 2015-11-15 21:36 ` David Kastrup 2015-11-15 7:05 ` Paul Eggert 2015-11-16 9:00 ` David Kastrup 2015-11-16 16:19 ` Eli Zaretskii 2015-11-15 16:01 ` David Kastrup 2015-11-15 19:36 ` Eli Zaretskii 2015-11-15 20:42 ` David Kastrup 2015-11-15 21:02 ` Eli Zaretskii 2015-11-16 23:17 ` Paul Eggert 2015-11-17 1:34 ` Random832 2015-11-17 3:42 ` Eli Zaretskii 2015-11-17 6:32 ` Paul Eggert 2015-11-17 9:08 ` Ulrich Mueller 2015-11-17 18:42 ` Paul Eggert 2015-11-17 20:32 ` Ulrich Mueller 2015-11-18 16:32 ` Achim Gratz 2015-11-18 17:10 ` David Kastrup 2015-11-18 17:38 ` Eli Zaretskii 2015-11-17 22:58 ` Richard Stallman 2015-11-17 12:13 ` David Kastrup 2015-11-17 18:32 ` Paul Eggert 2015-11-17 2:47 ` Tom Tromey 2015-11-20 2:20 ` Stefan Monnier 2015-11-20 8:44 ` Eli Zaretskii 2015-11-20 16:27 ` John Wiegley 2015-11-12 16:29 ` Juanma Barranquero 2015-10-16 8:28 ` Juanma Barranquero 2015-10-16 8:40 ` Paul Eggert 2015-10-16 8:18 ` David Kastrup 2015-10-16 8:49 ` Paul Eggert 2015-10-16 9:00 ` David Kastrup 2015-10-16 9:06 ` Eli Zaretskii 2015-10-16 9:18 ` David Kastrup 2015-10-16 10:09 ` Eli Zaretskii 2015-10-16 10:27 ` David Kastrup 2015-10-16 13:20 ` Eli Zaretskii 2015-10-16 14:03 ` David Kastrup 2015-10-16 16:01 ` Eli Zaretskii 2015-10-16 16:28 ` David Kastrup 2015-10-16 15:53 ` Stephen J. Turnbull 2015-10-16 16:01 ` David Kastrup 2015-10-15 23:11 ` Dynamic loading progress Philipp Stephani 2015-10-15 23:15 ` Philipp Stephani 2015-10-19 22:38 ` Philipp Stephani 2015-10-20 1:58 ` Daniel Colascione 2015-10-20 3:05 ` Tom Tromey 2015-10-20 3:13 ` Daniel Colascione 2015-10-20 3:32 ` Tom Tromey 2015-10-20 3:38 ` Daniel Colascione 2015-10-20 15:48 ` Stephen Leake 2015-10-20 18:52 ` Philipp Stephani 2015-10-22 12:57 ` Aurélien Aptel 2015-10-22 17:56 ` Aurélien Aptel 2015-10-22 18:03 ` Eli Zaretskii 2015-10-22 22:49 ` Philipp Stephani 2015-10-22 22:52 ` Daniel Colascione 2015-10-23 7:05 ` Eli Zaretskii 2015-10-23 7:17 ` Daniel Colascione 2015-10-23 7:00 ` Eli Zaretskii 2015-10-25 16:26 ` Aurélien Aptel 2015-10-25 16:31 ` Philipp Stephani 2015-10-25 18:45 ` Aurélien Aptel 2015-10-25 20:13 ` Philipp Stephani 2015-10-25 20:40 ` Philipp Stephani 2015-10-25 20:55 ` Aurélien Aptel 2015-10-28 13:47 ` Aurélien Aptel 2015-11-06 15:52 ` Ted Zlatanov 2015-11-06 15:55 ` Eli Zaretskii 2015-11-06 16:22 ` Ted Zlatanov 2015-11-07 1:53 ` Feature freezes and Emacs 25 (was: Dynamic loading progress) John Wiegley 2015-11-07 8:32 ` Feature freezes and Emacs 25 David Kastrup 2015-11-07 8:46 ` Eli Zaretskii 2015-11-07 8:33 ` Feature freezes and Emacs 25 (was: Dynamic loading progress) Eli Zaretskii 2015-11-09 21:55 ` Feature freezes and Emacs 25 John Wiegley 2015-11-09 22:08 ` Dmitry Gutov 2015-11-10 18:17 ` Richard Stallman 2015-11-10 18:23 ` Dmitry Gutov 2015-11-11 16:58 ` Richard Stallman 2015-11-09 23:59 ` Xue Fuqiao 2015-11-10 0:07 ` John Wiegley 2015-11-10 8:41 ` Xue Fuqiao 2015-11-10 13:25 ` Xue Fuqiao 2015-11-10 17:42 ` Nicolas Petton 2015-11-10 17:50 ` Eli Zaretskii 2015-11-10 18:13 ` Drew Adams 2015-11-11 16:57 ` Richard Stallman 2015-11-11 1:53 ` Xue Fuqiao 2015-11-11 19:59 ` Glenn Morris 2015-11-12 8:53 ` Xue Fuqiao 2015-11-15 2:42 ` Glenn Morris 2015-11-16 10:38 ` Juanma Barranquero 2015-11-16 16:54 ` John Wiegley 2015-11-18 18:12 ` Glenn Morris 2015-11-18 18:36 ` Glenn Morris 2015-11-18 22:06 ` John Wiegley 2015-11-10 9:41 ` Nicolas Petton 2015-11-10 14:22 ` John Wiegley 2015-11-10 16:38 ` Eli Zaretskii 2015-11-10 17:34 ` Nicolas Petton 2015-11-10 17:39 ` Nicolas Petton 2015-11-10 18:01 ` Eli Zaretskii 2015-11-11 16:47 ` Nicolas Petton 2015-11-10 16:24 ` Eli Zaretskii 2015-11-11 0:17 ` Juri Linkov 2015-11-11 1:16 ` John Wiegley 2015-11-12 0:43 ` Juri Linkov 2015-11-12 1:05 ` John Wiegley 2015-11-12 4:01 ` Artur Malabarba 2015-11-12 16:48 ` John Wiegley 2015-11-12 17:33 ` Eli Zaretskii 2015-11-12 19:01 ` Artur Malabarba 2015-11-15 1:51 ` Xue Fuqiao 2015-11-16 16:12 ` Eli Zaretskii 2015-11-16 23:59 ` Xue Fuqiao 2015-11-17 3:43 ` Eli Zaretskii 2015-11-18 0:47 ` Xue Fuqiao 2015-11-12 21:38 ` Design of commands operating on rectangular regions (was: Feature freezes and Emacs 25) Juri Linkov 2015-11-20 19:10 ` Design of commands operating on rectangular regions John Wiegley 2015-11-20 19:19 ` Drew Adams 2015-11-23 0:07 ` Juri Linkov 2015-11-23 1:53 ` Drew Adams 2015-11-22 23:57 ` Juri Linkov 2015-11-11 1:21 ` Feature freezes and Emacs 25 Drew Adams 2015-11-07 10:59 ` Phillip Lord 2015-11-07 14:20 ` kqueue in Emacs 25.1? (was: Feature freezes and Emacs 25) Michael Albinus 2015-11-07 14:39 ` Eli Zaretskii 2015-11-07 14:53 ` kqueue in Emacs 25.1? Michael Albinus 2015-11-07 15:26 ` Eli Zaretskii 2015-11-09 22:31 ` John Wiegley 2015-11-10 13:56 ` Michael Albinus 2015-11-10 14:32 ` Wolfgang Jenkner 2015-11-10 14:52 ` Michael Albinus 2015-11-11 11:41 ` Michael Albinus 2015-11-11 15:11 ` Wolfgang Jenkner 2015-11-11 15:44 ` Michael Albinus 2015-11-11 16:02 ` Wolfgang Jenkner 2015-11-11 16:48 ` Michael Albinus 2015-11-11 15:37 ` Wolfgang Jenkner 2015-11-11 15:52 ` Michael Albinus 2015-11-12 17:59 ` Michael Albinus 2015-11-12 18:34 ` Wolfgang Jenkner 2015-11-13 10:09 ` Michael Albinus 2015-11-13 13:00 ` Wolfgang Jenkner 2015-11-13 14:57 ` Wolfgang Jenkner 2015-11-13 16:23 ` Michael Albinus 2015-11-16 11:58 ` Michael Albinus 2015-11-17 3:50 ` John Wiegley 2015-11-17 9:37 ` Michael Albinus 2015-11-25 14:35 ` kqueue in Emacs 25? Michael Albinus 2015-11-25 18:53 ` John Wiegley 2015-11-07 14:52 ` kqueue in Emacs 25.1? Wolfgang Jenkner 2015-11-07 15:02 ` Wolfgang Jenkner 2015-11-08 6:33 ` Paul Eggert 2015-11-08 12:38 ` Wolfgang Jenkner 2015-11-07 18:57 ` Michael Albinus 2015-11-07 22:22 ` Wolfgang Jenkner 2015-11-06 21:52 ` Dynamic loading progress John Wiegley 2015-11-07 8:35 ` Eli Zaretskii 2015-11-07 13:33 ` Ted Zlatanov 2015-11-07 13:48 ` Eli Zaretskii 2015-11-07 14:01 ` Ted Zlatanov 2015-11-07 17:47 ` Aurélien Aptel 2015-11-08 11:16 ` Philipp Stephani 2015-11-08 12:54 ` Steinar Bang 2015-11-08 13:39 ` Philipp Stephani 2015-11-08 13:08 ` Ted Zlatanov 2015-11-08 13:42 ` Philipp Stephani 2015-11-08 20:38 ` Ted Zlatanov 2015-11-09 10:40 ` Aurélien Aptel 2015-11-09 10:48 ` Aurélien Aptel 2015-11-09 10:57 ` Yuri Khan 2015-11-09 11:46 ` Ted Zlatanov 2015-11-09 12:27 ` Aurélien Aptel 2015-11-09 13:18 ` Steinar Bang 2015-11-09 13:47 ` Steinar Bang 2015-11-09 14:26 ` Aurélien Aptel 2015-11-09 14:52 ` Aurélien Aptel 2015-11-09 19:58 ` Aurélien Aptel 2015-11-10 20:07 ` Philipp Stephani 2015-11-09 13:38 ` Ted Zlatanov 2015-11-09 16:16 ` Philipp Stephani 2015-11-11 11:22 ` Ted Zlatanov 2015-11-11 13:57 ` Philipp Stephani 2015-11-13 1:29 ` Aurélien Aptel 2015-11-13 11:35 ` Ted Zlatanov 2015-11-13 15:39 ` Freeze is almost here (was: Dynamic loading progress) John Wiegley 2015-11-13 16:43 ` Juanma Barranquero 2015-11-13 19:24 ` Eli Zaretskii 2015-11-13 19:37 ` Eli Zaretskii 2015-11-13 20:05 ` Freeze is almost here Achim Gratz 2015-11-13 20:17 ` Eli Zaretskii 2015-11-13 20:36 ` Achim Gratz 2015-11-13 20:46 ` Eli Zaretskii 2015-11-13 21:46 ` Dmitry Gutov 2015-11-14 11:27 ` Artur Malabarba 2015-11-14 11:55 ` Eli Zaretskii 2015-11-14 12:34 ` Artur Malabarba 2015-11-14 17:08 ` Dmitry Gutov 2015-11-13 20:05 ` Freeze is almost here (was: Dynamic loading progress) Eli Zaretskii 2015-11-13 20:31 ` Eli Zaretskii 2015-11-13 22:57 ` Freeze is almost here John Wiegley 2015-11-14 8:42 ` Eli Zaretskii 2015-11-14 15:59 ` John Wiegley 2015-11-15 9:53 ` Steinar Bang 2015-11-16 9:28 ` Steinar Bang 2015-11-16 16:54 ` John Wiegley 2015-11-13 21:34 ` Andreas Schwab 2015-11-14 8:03 ` Eli Zaretskii 2015-11-14 8:16 ` Andreas Schwab 2015-11-14 8:27 ` Eli Zaretskii 2015-11-14 10:06 ` Andreas Schwab 2015-11-14 8:45 ` David Engster 2015-11-14 9:15 ` Eli Zaretskii 2015-11-14 12:54 ` David Engster 2015-11-14 12:57 ` David Engster 2015-11-14 13:36 ` Eli Zaretskii 2015-11-14 14:37 ` David Engster 2015-11-14 15:02 ` Eli Zaretskii 2015-11-14 13:33 ` Eli Zaretskii 2015-11-14 14:42 ` David Engster 2015-11-14 15:01 ` Eli Zaretskii 2015-11-14 0:56 ` Freeze is almost here (was: Dynamic loading progress) Xue Fuqiao 2015-11-14 6:06 ` Freeze is almost here John Wiegley 2015-11-14 8:22 ` Eli Zaretskii 2015-11-16 0:10 ` Dynamic loading progress Aurélien Aptel 2015-11-17 2:23 ` raman 2015-11-17 8:26 ` Steinar Bang 2015-11-17 11:08 ` Aurélien Aptel 2015-11-18 19:38 ` Ted Zlatanov 2015-11-18 20:58 ` Eli Zaretskii 2015-11-18 22:05 ` John Wiegley 2015-11-19 2:19 ` Ted Zlatanov 2015-11-19 3:39 ` Eli Zaretskii 2015-11-19 15:26 ` Eli Zaretskii 2015-11-19 15:55 ` Paul Eggert 2015-11-19 16:27 ` Eli Zaretskii 2015-11-19 16:37 ` Paul Eggert 2015-11-19 17:04 ` Eli Zaretskii 2015-11-19 17:26 ` Eli Zaretskii 2015-11-19 17:32 ` Paul Eggert 2015-11-19 17:50 ` Eli Zaretskii 2015-11-19 17:57 ` Stephen Leake 2015-11-19 18:06 ` Eli Zaretskii 2015-11-19 18:53 ` Paul Eggert 2015-11-19 20:27 ` Eli Zaretskii 2015-11-19 20:31 ` John Wiegley 2015-11-19 22:45 ` Philipp Stephani 2015-11-19 22:55 ` Paul Eggert 2015-11-19 23:08 ` Philipp Stephani 2015-11-19 23:50 ` Paul Eggert 2015-11-19 23:55 ` Philipp Stephani 2015-11-19 23:58 ` Paul Eggert 2015-11-20 19:23 ` Philipp Stephani 2015-11-20 21:04 ` Paul Eggert 2015-11-20 22:44 ` Philipp Stephani 2015-11-20 10:11 ` Eli Zaretskii 2015-11-20 20:00 ` Philipp Stephani 2015-11-19 22:41 ` Philipp Stephani 2015-11-19 23:51 ` Paul Eggert 2015-11-19 23:57 ` Philipp Stephani 2015-11-20 0:03 ` Paul Eggert 2015-11-20 19:29 ` Philipp Stephani 2015-11-20 20:47 ` Paul Eggert 2015-11-20 22:36 ` Philipp Stephani 2015-11-20 23:06 ` Paul Eggert 2015-11-21 8:54 ` Philipp Stephani 2015-11-21 23:25 ` Paul Eggert 2015-11-22 9:15 ` Philipp Stephani 2015-11-22 18:37 ` Paul Eggert 2015-11-22 19:17 ` Philipp Stephani 2015-11-20 9:53 ` Eli Zaretskii 2015-11-20 11:59 ` Eli Zaretskii 2015-11-20 15:52 ` Eli Zaretskii 2015-11-20 20:39 ` Paul Eggert 2015-11-20 21:22 ` Eli Zaretskii 2015-11-20 22:46 ` Philipp Stephani 2015-11-20 18:44 ` Paul Eggert 2015-11-20 18:50 ` Eli Zaretskii 2015-11-20 19:13 ` Paul Eggert 2015-11-20 20:05 ` Philipp Stephani 2015-11-20 20:32 ` Paul Eggert 2015-11-20 20:45 ` Philipp Stephani 2015-11-20 20:59 ` Paul Eggert 2015-11-20 22:42 ` Philipp Stephani 2015-11-20 23:44 ` Paul Eggert 2015-11-21 8:34 ` Philipp Stephani 2015-11-23 17:06 ` Ted Zlatanov 2015-11-20 19:58 ` Philipp Stephani 2015-11-20 21:56 ` Eli Zaretskii 2015-11-20 23:22 ` Philipp Stephani 2015-11-20 23:29 ` Paul Eggert 2015-11-21 0:08 ` Philipp Stephani 2015-11-21 0:28 ` Paul Eggert 2015-11-21 8:33 ` Philipp Stephani 2015-11-21 23:10 ` Paul Eggert 2015-11-22 9:03 ` Philipp Stephani 2015-11-22 16:23 ` Eli Zaretskii 2015-11-22 16:27 ` Philipp Stephani 2015-11-22 16:56 ` Eli Zaretskii 2015-11-22 17:18 ` Philipp Stephani 2015-11-22 17:27 ` Philipp Stephani 2015-11-22 18:50 ` Paul Eggert 2015-11-22 19:19 ` Philipp Stephani 2015-11-22 19:26 ` Eli Zaretskii 2015-11-22 19:58 ` Philipp Stephani 2015-11-23 18:17 ` Eli Zaretskii 2015-11-23 2:47 ` Tom Tromey 2015-11-23 3:46 ` Eli Zaretskii 2015-11-23 16:29 ` Paul Eggert 2015-11-23 16:35 ` Eli Zaretskii 2015-11-21 8:35 ` Eli Zaretskii 2015-11-21 9:19 ` Philipp Stephani 2015-11-21 9:33 ` Eli Zaretskii 2015-11-21 9:01 ` Philipp Stephani 2015-11-21 9:29 ` Eli Zaretskii 2015-11-21 10:31 ` Philipp Stephani 2015-11-21 10:45 ` David Kastrup 2015-11-21 11:10 ` Eli Zaretskii 2015-11-21 12:11 ` Philipp Stephani 2015-11-21 13:23 ` Eli Zaretskii 2015-11-22 9:25 ` Philipp Stephani 2015-11-22 14:56 ` Philipp Stephani 2015-11-22 18:04 ` Eli Zaretskii 2015-11-22 19:10 ` Philipp Stephani 2015-11-22 19:43 ` Eli Zaretskii 2015-11-22 17:35 ` Eli Zaretskii 2015-11-22 18:19 ` Philipp Stephani 2015-11-22 19:12 ` David Kastrup 2015-11-22 19:20 ` Eli Zaretskii 2015-11-22 19:37 ` Philipp Stephani 2015-11-22 19:49 ` David Kastrup 2015-11-22 19:50 ` Eli Zaretskii 2015-11-22 20:59 ` David Kastrup 2015-11-23 3:29 ` Eli Zaretskii 2015-11-22 21:10 ` Philipp Stephani 2015-11-23 3:31 ` Eli Zaretskii 2015-11-23 18:10 ` Eli Zaretskii 2015-11-19 22:14 ` Philipp Stephani 2015-11-23 16:57 ` Ted Zlatanov 2015-11-19 22:12 ` Philipp Stephani 2015-11-20 7:50 ` Eli Zaretskii 2015-11-20 22:10 ` Philipp Stephani 2015-11-20 23:46 ` Paul Eggert 2015-11-21 7:53 ` Eli Zaretskii 2015-11-21 8:30 ` Philipp Stephani 2015-11-21 9:06 ` Eli Zaretskii 2015-11-21 9:25 ` Philipp Stephani 2015-11-21 9:51 ` Eli Zaretskii 2015-11-21 10:33 ` Philipp Stephani 2015-11-21 10:53 ` Eli Zaretskii 2015-11-17 17:10 ` John Wiegley 2015-11-18 0:17 ` Xue Fuqiao 2015-11-18 1:20 ` Xue Fuqiao 2015-11-18 3:08 ` John Wiegley 2015-11-09 13:16 ` Steinar Bang 2015-11-10 9:35 ` Suggestion to enable git rerere by default Nicolas Richard 2015-11-10 11:12 ` Artur Malabarba 2015-11-10 13:01 ` Nicolas Richard 2015-11-09 22:10 ` Dynamic loading progress John Wiegley 2015-11-10 1:40 ` Ted Zlatanov 2015-11-08 11:02 ` Philipp Stephani 2015-11-08 12:51 ` Steinar Bang 2015-11-08 13:35 ` Philipp Stephani 2015-10-14 22:34 ` Philipp Stephani 2015-10-14 22:38 ` Daniel Colascione 2015-10-14 23:32 ` Aurélien Aptel 2015-10-15 1:05 ` Philipp Stephani 2015-10-15 10:50 ` Aurélien Aptel 2015-10-15 19:25 ` Stephen Leake 2015-02-15 18:24 ` Andreas Schwab 2015-02-15 18:39 ` Stefan Monnier 2015-02-12 21:39 ` Aurélien Aptel 2015-02-13 21:29 ` Stephen Leake 2015-02-04 12:11 ` Ted Zlatanov 2015-02-04 15:22 ` Stefan Monnier 2015-02-04 21:49 ` Aurélien Aptel 2015-02-04 23:00 ` Ted Zlatanov
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).