emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] emacs-26 ce8b458: Document in the ELisp manual how to writ


From: Eli Zaretskii
Subject: [Emacs-diffs] emacs-26 ce8b458: Document in the ELisp manual how to write loadable modules
Date: Thu, 11 Oct 2018 13:54:43 -0400 (EDT)

branch: emacs-26
commit ce8b4584a3c69e5c4abad8a0a9c3781ce8c0c1f8
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    Document in the ELisp manual how to write loadable modules
    
    * doc/lispref/internals.texi (Writing Dynamic Modules)
    (Module Initialization, Module Functions, Module Values)
    (Module Misc, Module Nonlocal): New nodes.
    * doc/lispref/loading.texi (Dynamic Modules): Add
    cross-reference to the new node.
    * doc/lispref/internals.texi (GNU Emacs Internals):
    * doc/lispref/elisp.texi (Top): Update menus for the new nodes.
---
 doc/lispref/elisp.texi     |   9 +
 doc/lispref/internals.texi | 703 +++++++++++++++++++++++++++++++++++++++++++++
 doc/lispref/loading.texi   |  33 ++-
 3 files changed, 734 insertions(+), 11 deletions(-)

diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi
index 6c3182b..7dd1e89 100644
--- a/doc/lispref/elisp.texi
+++ b/doc/lispref/elisp.texi
@@ -1588,9 +1588,18 @@ GNU Emacs Internals
 * Memory Usage::            Info about total size of Lisp objects made so far.
 * C Dialect::               What C variant Emacs is written in.
 * Writing Emacs Primitives::  Writing C code for Emacs.
+* Writing Dynamic Modules::   Writing loadable modules for Emacs.
 * Object Internals::        Data formats of buffers, windows, processes.
 * C Integer Types::         How C integer types are used inside Emacs.
 
+Writing Dynamic Modules
+
+* Module Initialization::
+* Module Functions::
+* Module Values::
+* Module Misc::
+* Module Nonlocal::
+
 Object Internals
 
 * Buffer Internals::        Components of a buffer structure.
diff --git a/doc/lispref/internals.texi b/doc/lispref/internals.texi
index 45c3b87..8db8c06 100644
--- a/doc/lispref/internals.texi
+++ b/doc/lispref/internals.texi
@@ -18,6 +18,7 @@ internal aspects of GNU Emacs that may be of interest to C 
programmers.
 * Memory Usage::        Info about total size of Lisp objects made so far.
 * C Dialect::           What C variant Emacs is written in.
 * Writing Emacs Primitives::   Writing C code for Emacs.
+* Writing Dynamic Modules::    Writing loadable modules for Emacs.
 * Object Internals::    Data formats of buffers, windows, processes.
 * C Integer Types::     How C integer types are used inside Emacs.
 @end menu
@@ -980,6 +981,708 @@ in @file{byte-opt.el} that binds 
@code{side-effect-free-fns} and
 @code{side-effect-and-error-free-fns} so that the compiler optimizer
 knows about it.
 
address@hidden Writing Dynamic Modules
address@hidden Writing Dynamically-Loaded Modules
address@hidden writing emacs modules
address@hidden dynamic modules, writing
+
address@hidden module @acronym{API}
+  This section describes the Emacs module @acronym{API} and how to use
+it as part of writing extension modules for Emacs.  The module
address@hidden is defined in the C programming language, therefore the
+description and the examples in this section assume the module is
+written in address@hidden  For other programming languages, you will need to 
use
+the appropriate bindings, interfaces and facilities for calling C code.
+Emacs C code requires a C99 or later compiler (@pxref{C Dialect}), and
+so the code examples in this section also follow that standard.
+
+Writing a module and integrating it into Emacs comprises the following
+tasks:
+
address@hidden @bullet
address@hidden
+Writing initialization code for the module.
+
address@hidden
+Writing one or more module functions.
+
address@hidden
+Communicating values and objects between Emacs and your module
+functions.
+
address@hidden
+Handling of error conditions and nonlocal exits.
address@hidden itemize
+
address@hidden
+The following subsections describe these tasks and the @acronym{API}
+itself in more detail.
+
+Once your module is written, compile it to produce a shared library,
+according to the conventions of the underlying platform.  Then place
+the shared library in a directory mentioned in @code{load-path}
+(@pxref{Library Search}), where Emacs will find it.
+
+If you wish to verify the conformance of a modue to the Emacs dynamic
+module @acronym{API}, invoke Emacs with the @kbd{--module-assertions}
+option.  @xref{Initial Options,,,emacs, The GNU Emacs Manual}.
+
address@hidden
+* Module Initialization::
+* Module Functions::
+* Module Values::
+* Module Misc::
+* Module Nonlocal::
address@hidden menu
+
address@hidden Module Initialization
address@hidden Module Initialization Code
address@hidden module initialization
+
+  Begin your module by including the header file @file{emacs-module.h}
+and defining the GPL compatibility symbol:
+
address@hidden
+#include <emacs-module.h>
+
+int plugin_is_GPL_compatible;
address@hidden example
+
+The @file{emacs-module.h} file is installed into your system's include
+tree as part of the Emacs installation.  Alternatively, you can find
+it in the Emacs source tree.
+
address@hidden initialization function}
+Next, write an initialization function for the module.
+
address@hidden Function int emacs_module_init (struct emacs_runtime 
address@hidden)
+Emacs calls this function when it loads a module.  If a module does
+not export a function named @code{emacs_module_init}, trying to load
+the module will signal an error.  The initialization function should
+return zero if the initialization succeeds, non-zero otherwise.  In
+the latter case, Emacs will signal an error, and the loading of the
+module will fail.  If the user presses @kbd{C-g} during the
+initialization, Emacs ignores the return value of the initialization
+function and quits (@pxref{Quitting}).  (If needed, you can catch user
+quitting inside the initialization function, @pxref{should_quit}.)
+
+The argument @var{runtime} is a pointer to a C @code{struct} that
+includes 2 public fields: @code{size}, which provides the size of the
+structure in bytes; and @code{get_environment}, which provides a
+pointer to a function that allows the module initialization function
+access to the Emacs environment object and its interfaces.
+
+The initialization function should perform whatever initialization is
+required for the module.  In addition, it can perform the following
+tasks:
+
address@hidden @asis
address@hidden compatibility, between modules and Emacs
address@hidden Compatibility verification
+A module can verify that the Emacs executable which loads the module
+is compatible with the module, by comparing the @code{size} member of
+the @var{runtime} structure with the value compiled into the module:
+
address@hidden
+int
+emacs_module_init (struct emacs_runtime *ert)
address@hidden
+  if (ert->size < sizeof (*ert))
+    return 1;
address@hidden
address@hidden example
+
address@hidden
+If the size of the runtime object passed to the module is smaller than
+what it expects, it means the module was compiled for an Emacs version
+newer (later) than the one which attempts to load it, i.e.@: the
+module might be incompatible with the Emacs binary.
+
+In addition, a module can verify the compatibility of the module
address@hidden with what the module expects.  The following sample code
+assumes it is part of the @code{emacs_module_init} function shown
+above:
+
address@hidden
+  emacs_env *env = ert->get_environment (ert);
+  if (env->size < sizeof (*env))
+    return 2;
address@hidden example
+
address@hidden
address@hidden module runtime environment
+This calls the @code{get_environment} function using the pointer
+provided in the @code{runtime} structure to retrieve a pointer to the
address@hidden's @dfn{environment}, a C @code{struct} which also has a
address@hidden field holding the size of the structure in bytes.
+
+Finally, you can write a module that will work with older versions of
+Emacs, by comparing the size of the environment passed by Emacs with
+known sizes, like this:
+
address@hidden
+  emacs_env *env = ert->get_environment (ert);
+  if (env->size >= sizeof (struct emacs_env_26))
+    emacs_version = 26;  /* Emacs 26 or later.  */
+  else if (env->size >= sizeof (struct emacs_env_25))
+    emacs_version = 25;
+  else
+    return 2; /* Unknown or unsupported version.  */
address@hidden example
+
address@hidden
+This works because later Emacs versions always @emph{add} members to
+the environment, never @emph{remove} any members, so the size can only
+grow with new Emacs releases.  Given the version of Emacs, the module
+can use only the parts of the module @acronym{API} that existed in
+that version, since those parts are identical in later versions.
+
+We recommend that modules always perform the compatibility
+verification, unless they do their job entirely in the initialization
+function, and don't access any Lisp objects or use any Emacs functions
+accessible through the environment structure.
+
address@hidden Binding module functions to Lisp symbols
+This gives the module functions names so that Lisp code could call it
+by that name.  We describe how to do this in @ref{Module Functions}
+below.
address@hidden table
address@hidden deftypefn
+
address@hidden Module Functions
address@hidden Writing Module Functions
address@hidden writing module functions
address@hidden module functions
+
+  The main reason for writing an Emacs module is to make additional
+functions available to Lisp programs that load the module.  This
+subsection describes how to write such @dfn{module functions}.
+
+A module function has the following general form and signature:
+
address@hidden Function emacs_value module_func (emacs_env address@hidden, 
ptrdiff_t @var{nargs}, emacs_value address@hidden, void address@hidden)
+The @var{env} argument provides a pointer to the @acronym{API}
+environment, needed to access Emacs objects and functions.  The
address@hidden argument is the required number of arguments, which can be
+zero (see @code{make_function} below for more flexible specification
+of the argument number), and @var{args} is a pointer to the array of
+the function arguments.  The argument @var{data} points to additional
+data required by the function, which was arranged when
address@hidden (see below) was called to create an Emacs
+function from @code{module_func}.
+
+Module functions use the type @code{emacs_value} to communicate Lisp
+objects between Emacs and the module (@pxref{Module Values}).  The
address@hidden, described below and in the following subsections,
+provides facilities for conversion between basic C data types and the
+corresponding @code{emacs_value} objects.
+
+A module function always returns a value.  If the function returns
+normally, the Lisp code which called it will see the Lisp object
+corresponding to the @code{emacs_value} value the function returned.
+However, if the user typed @kbd{C-g}, or if the module function or its
+callees signaled an error or exited nonlocally (@pxref{Module
+Nonlocal}), Emacs will ignore the returned value and quit or throw as
+it does when Lisp code encounters the same situations.
address@hidden deftypefn
+
+After writing your C code for a module function, you should make a
+Lisp function object from it using @code{make_function}.  This is
+normally done in the module initialization function (@pxref{module
+initialization function}), after verifying the @acronym{API}
+compatibility, and uses the pointer to @code{make_function} provided
+in the environment (recall that the pointer to the environment is
+returned by @code{get_environment}).
+
address@hidden Function emacs_value make_function (emacs_env address@hidden, 
ptrdiff_t @var{min_arity}, ptrdiff_t @var{max_arity}, subr @var{func}, const 
char address@hidden, void address@hidden)
address@hidden emacs_variadic_function
+This returns an Emacs function created from the C function @var{func},
+whose signature is as described for @code{module_func} above (assumed
+here to be @code{typedef}'ed as @code{subr}).  The arguments
address@hidden and @var{max_arity} specify the minimum and maximum
+number of arguments that @var{func} can accept.  The @var{max_arity}
+argument can have the special value @code{emacs_variadic_function},
+which makes the function accept an unlimited number of arguments, like
+the @code{&rest} keyword in Lisp (@pxref{Argument List}).
+
+The argument @var{data} is a way to arrange for arbitrary additional
+data to be passed to @var{func} when it is called.  Whatever pointer
+is passed to @code{make_function} will be passed unaltered to
address@hidden
+
+The argument @var{docstring} specifies the documentation string for
+the function.  It should be either an @acronym{ASCII} string, or a
+UTF-8 encoded address@hidden string, or a @code{NULL} pointer; in
+the latter case the function will have no documentation.  The
+documentation string can end with a line that specifies the advertised
+calling convention, see @ref{Function Documentation}.
+
+Since every module function must accept the pointer to the environment
+as its first argument, the call to @code{make_function} could be made
+from any module function, but you will normally want to do that from
+the module initialization function, so that all the module functions
+are known to Emacs once the module is loaded.
address@hidden deftypefn
+
+Finally, you should bind the Lisp function to a symbol, so that Lisp
+code could call your function by name.  For that, use the module
address@hidden function @code{intern} (@pxref{intern}) whose pointer is
+also provided in the environment that module functions can access.
+
+Combining the above steps, code that arranges for a C function
address@hidden to be callable as @code{module-func} from Lisp will
+look like this, as part of the module initialization function:
+
address@hidden
+ emacs_env *env = ert->get_environment (ert);
+ emacs_value func = env->make_function (env, min_arity, max_arity,
+                                        module_func, docstring, data);
+ emacs_value symbol = env->intern (env, "module-func");
+ emacs_value args[] = @{symbol, address@hidden;
+ env->funcall (env, env->intern (env, "defalias"), 2, args);
address@hidden example
+
address@hidden
+This makes the symbol @code{module-func} known to Emacs by calling
address@hidden>intern}, then invokes @code{defalias} from Emacs to bind
+the function to that symbol.  Note that it is possible to use
address@hidden instead of @code{defalias}; the differences are described
+in @ref{Defining Functions, defalias}.
+
+Using the module @acronym{API}, it is possible to define more complex
+function and data types: interactive functions, inline functions,
+macros, etc.  However, the resulting C code will be cumbersome and
+hard to read.  Therefore, we recommend that you limit the module code
+which creates functions and data structures to the absolute minimum,
+and leave the rest for a Lisp package that will accompany your module,
+because doing these additional tasks in Lisp is much easier, and will
+produce a much more readable code.  For example, given a module
+function @code{module-func} defined as above, one way of making an
+interactive command @code{module-cmd} based on it is with the
+following simple Lisp wrapper:
+
address@hidden
+(defun module-cmd (&rest args)
+  "Documentation string for the command."
+  (interactive @var{spec})
+  (apply 'module-func args))
address@hidden lisp
+
+The Lisp package which goes with your module could then load the
+module using the @code{module-load} primitive (@pxref{Dynamic
+Modules}) when the package is loaded into Emacs.
+
address@hidden Module Values
address@hidden Conversion Between Lisp and Module Values
address@hidden module values, conversion
+
address@hidden @code{emacs_value} data type
+  With very few exceptions, most modules need to exchange data with
+Lisp programs that call them: accept arguments to module functions and
+return values from module functions.  For this purpose, the module
address@hidden provides the @code{emacs_value} type, which represents
+Emacs Lisp objects communicated via the @acronym{API}; it is the
+functional equivalent of the @code{Lisp_Object} type used in Emacs C
+primitives (@pxref{Writing Emacs Primitives}).  This section describes
+the parts of the module @acronym{API} that allow to create
address@hidden objects corresponding to basic Lisp data types, and
+how to access from C data in @code{emacs_value} objects that
+correspond to Lisp objects.
+
+All of the functions described below are actually @emph{function
+pointers} provided via the pointer to the environment which every
+module function accepts.  Therefore, module code should call these
+functions through the environment pointer, like this:
+
address@hidden
+emacs_env *env;  /* the environment pointer */
+env->some_function (address@hidden);
address@hidden example
+
address@hidden
+The @code{emacs_env} pointer will usually come from the first argument
+to the module function, or from the call to @code{get_environment} if
+you need the environment in the module initialization function.
+
+Most of the functions described below became available in Emacs 25,
+the first Emacs release that supported dynamic modules.  For the few
+functions that became available in later Emacs releases, we mention
+the first Emacs version that supported them.
+
+The following @acronym{API} functions extract values of various C data
+types from @code{emacs_value} objects.  They all raise the
address@hidden error condition (@pxref{Type Predicates})
+if the argument @code{emacs_value} object is not of the type expected
+by the function.  @xref{Module Nonlocal}, for details of how signaling
+errors works in Emacs modules, and how to catch error conditions
+inside the module before they are reported to Emacs.  The
address@hidden function @code{type_of} (@pxref{Module Misc, type_of})
+can be used to obtain the type of a @code{emacs_value} object.
+
address@hidden Function intmax_t extract_integer (emacs_env address@hidden, 
emacs_value @var{arg})
+This function returns the value of a Lisp integer specified by
address@hidden  The C data type of the return value, @code{intmax_t}, is
+the widest integral data type supported by the C compiler, typically
address@hidden@code{long long}}.
address@hidden deftypefn
+
address@hidden Function double extract_float (emacs_env address@hidden, 
emacs_value @var{arg})
+This function returns the value of a Lisp float specified by
address@hidden, as a C @code{double} value.
address@hidden deftypefn
+
address@hidden Function bool copy_string_contents (emacs_env address@hidden, 
emacs_value @var{arg}, char address@hidden, ptrdiff_t address@hidden)
+This function stores the UTF-8 encoded text of a Lisp string specified
+by @var{arg} in the array of @code{char} pointed by @var{buf}, which
+should have enough space to hold at least @address@hidden bytes,
+including the terminating null byte.  The argument @var{len} must not
+be a @code{NULL} pointer, and, when the function is called, it should
+point to a value that specifies the size of @var{buf} in bytes.
+
+If the buffer size specified by @address@hidden is large enough to
+hold the string's text, the function stores in @address@hidden the
+actual number of bytes copied to @var{buf}, including the terminating
+null byte, and returns @code{true}.  If the buffer is too small, the
+function raises the @code{args-out-of-range} error condition, stores
+the required number of bytes in @address@hidden, and returns
address@hidden  @xref{Module Nonlocal}, for how to handle pending error
+conditions.
+
+The argument @var{buf} can be a @code{NULL} pointer, in which case the
+function stores in @address@hidden the number of bytes required for
+storing the contents of @var{arg}, and returns @code{true}.  This is
+how you can determine the size of @var{buf} needed to store a
+particular string: first call @code{copy_string_contents} with
address@hidden as @var{buf}, then allocate enough memory to hold the
+number of bytes stored by the function in @address@hidden, and call
+the function again with address@hidden @var{buf} to actually perform
+the text copying.
address@hidden deftypefn
+
address@hidden Function emacs_value vec_get (emacs_env address@hidden, 
emacs_value @var{vector}, ptrdiff_t @var{index})
+This function returns the element of @var{vector} at @var{index}.  The
address@hidden of the first vector element is zero.  The function raises
+the @code{args-out-of-range} error condition if the value of
address@hidden is invalid.  To extract C data from the value the function
+returns, use the other extraction functions described here, as
+appropriate for the Lisp data type stored in that element of the
+vector.
address@hidden deftypefn
+
address@hidden Function ptrdiff_t vec_size (emacs_env address@hidden, 
emacs_value @var{vector})
+This function returns the number of elements in @var{vector}.
address@hidden deftypefn
+
address@hidden Function void vec_set (emacs_env address@hidden, emacs_value 
@var{vector}, ptrdiff_t @var{index}, emacs_value @var{value})
+This function stores @var{value} in the element of @var{vector} whose
+index is @var{index}.  It raises the @code{args-out-of-range} error
+condition if the value of @var{index} is invalid.
address@hidden deftypefn
+
+The following @acronym{API} functions create @code{emacs_value}
+objects from basic C data types.  They all return the created
address@hidden object.
+
address@hidden Function emacs_value make_integer (emacs_env address@hidden, 
intmax_t @var{n})
+This function takes an integer argument @var{n} and returns the
+corresponding @code{emacs_value} object.  It raises the
address@hidden error condition if the value of @var{n} cannot
+be represented as an Emacs integer, i.e.@: is not inside the limits
+set by @code{most-negative-fixnum} and @code{most-positive-fixnum}
+(@pxref{Integer Basics}).
address@hidden deftypefn
+
address@hidden Function emacs_value make_float (emacs_env address@hidden, 
double @var{d})
+This function takes a @code{double} argument @var{d} and returns the
+corresponding Emacs floating-point value.
address@hidden deftypefn
+
address@hidden Function emacs_value make_string (emacs_env address@hidden, 
const char address@hidden, ptrdiff_t @var{strlen})
+This function creates an Emacs string from C text string pointed by
address@hidden whose length in bytes, not including the terminating null
+byte, is @var{strlen}.  The original string in @var{str} can be either
+an @acronym{ASCII} string or a UTF-8 encoded address@hidden
+string; it can include embedded null bytes, and doesn't have to end in
+a terminating null byte at @address@hidden@var{strlen}]}.  The
+function raises the @code{overflow-error} error condition if
address@hidden is negative or exceeds the maximum length of an Emacs
+string.
address@hidden deftypefn
+
+The @acronym{API} does not provide functions to manipulate Lisp data
+structures, for example, create lists with @code{cons} and @code{list}
+(@pxref{Building Lists}), extract list members with @code{car} and
address@hidden (@pxref{List Elements}), create vectors with @code{vector}
+(@pxref{Vector Functions}), etc.  For these, use @code{intern} and
address@hidden, described in the next subsection, to call the
+corresponding Lisp functions.
+
+Normally, @code{emacs_value} objects have a rather short lifetime: it
+ends when the @code{emacs_env} pointer used for their creation goes
+out of scope.  Occasionally, you may need to create @dfn{global
+references}: @code{emacs_value} objects that live as long as you
+wish.  Use the following two functions to manage such objects.
+
address@hidden Function emacs_value make_global_ref (emacs_env address@hidden, 
emacs_value @var{value})
+This function returns a global reference for @var{value}.
address@hidden deftypefn
+
address@hidden Function void free_global_ref (emacs_env address@hidden, 
emacs_value @var{global_value})
+This function frees the @var{global_value} previously created by
address@hidden  The @var{global_value} is no longer valid
+after the call.  Your module code should pair each call to
address@hidden with the corresponding @code{free_global_ref}.
address@hidden deftypefn
+
address@hidden user pointer, using in module functions
+An alternative to keeping around C data structures that need to be
+passed to module functions later is to create @dfn{user pointer}
+objects.  A user pointer, or @code{user-ptr}, object is a Lisp object
+that encapsulates a C pointer and can have an associated finalizer
+function, which is called when the object is garbage-collected
+(@pxref{Garbage Collection}).  The module @acronym{API} provides
+functions to create and access @code{user-ptr} objects.  These
+functions raise the @code{wrong-type-argument} error condition if they
+are called on @code{emacs_value} that doesn't represent a
address@hidden object.
+
address@hidden Function emacs_value make_user_ptr (emacs_env address@hidden, 
emacs_finalizer @var{fin}, void address@hidden)
+This function creates and returns a @code{user-ptr} object which wraps
+the C pointer @var{ptr}.  The finalizer function @var{fin} can be a
address@hidden pointer (meaning no finalizer), or it can be a function of
+the following signature:
+
address@hidden
+typedef void (*emacs_finalizer) (void address@hidden);
address@hidden example
+
address@hidden
+If @var{fin} is not a @code{NULL} pointer, it will be called with the
address@hidden as the argument when the @code{user-ptr} object is
+garbage-collected.  Don't run any expensive code in a finalizer,
+because GC must finish quickly to keep Emacs responsive.
address@hidden deftypefn
+
address@hidden Function void *get_user_ptr (emacs_env address@hidden, 
emacs_value val)
+This function extracts the C pointer from the Lisp object represented
+by @var{val}.
address@hidden deftypefn
+
address@hidden Function void set_user_ptr (emacs_env address@hidden, 
emacs_value @var{value}, void address@hidden)
+This function sets the C pointer embedded in the @code{user-ptr}
+object represented by @var{value} to @var{ptr}.
address@hidden deftypefn
+
address@hidden Function emacs_finalizer get_user_finalizer (emacs_env 
address@hidden, emacs_value val)
+This function returns the finalizer of the @code{user-ptr} object
+represented by @var{val}, or @code{NULL} if it doesn't have a finalizer.
address@hidden deftypefn
+
address@hidden Function void set_user_finalizer (emacs_env address@hidden, 
emacs_value @var{val}, emacs_finalizer @var{fin})
+This function changes the finalizer of the @code{user-ptr} object
+represented by @var{val} to be @var{fin}.  If @var{fin} is a
address@hidden pointer, the @code{user-ptr} object will have no finalizer.
address@hidden deftypefn
+
address@hidden Module Misc
address@hidden Miscellaneous Convenience Functions for Modules
+
+  This subsection describes a few convenience functions provided by
+the module @acronym{API}.  Like the functions described in previous
+subsections, all of them are actually function pointers, and need to
+be called via the @code{emacs_env} pointer.  Description of functions
+that were introduced after Emacs 25 calls out the first version where
+they became available.
+
address@hidden Function bool eq (emacs_env address@hidden, emacs_value 
@var{val1}, emacs_value @var{val2})
+This function returns @code{true} if the Lisp objects represented by
address@hidden and @var{val2} are identical, @code{false} otherwise.  This
+is the same as the Lisp function @code{eq} (@pxref{Equality
+Predicates}), but avoids the need to intern the objects represented by
+the arguments.
+
+There are no @acronym{API} functions for other equality predicates, so
+you will need to use @code{intern} and @code{funcall}, described
+below, to perform more complex equality tests.
address@hidden deftypefn
+
address@hidden Function bool is_not_nil (emacs_env address@hidden, emacs_value 
@var{val})
+This function tests whether the Lisp object represented by @var{val}
+is address@hidden; it returns @code{true} or @code{false} accordingly.
+
+Note that you could implement an equivalent test by using
address@hidden to get an @code{emacs_value} representing @code{nil},
+then use @code{eq}, described above, to test for equality.  But using
+this function is more convenient.
address@hidden deftypefn
+
address@hidden Function emacs_value type_of (emacs_env address@hidden, 
emacs_value @code{object})
+This function returns the type of @var{object} as a value that
+represents a symbol: @code{string} for a string, @code{integer} for an
+integer, @code{process} for a process, etc.  @xref{Type Predicates}.
+You can use @code{intern} and @code{eq} to compare against known type
+symbols, if your code needs to depend on the object type.
address@hidden deftypefn
+
address@hidden
address@hidden Function emacs_value intern (emacs_env address@hidden, const 
char *name)
+This function returns an interned Emacs symbol whose name is
address@hidden, which should be an @acronym{ASCII} null-terminated string.
+It creates a new symbol if one does not already exist.
+
+Together with @code{funcall}, described below, this function provides
+a means for invoking any Lisp-callable Emacs function, provided that
+its name is a pure @acronym{ASCII} string.  For example, here's how to
+intern a symbol whose name @code{name_str} is address@hidden, by
+calling the more powerful Emacs @code{intern} function
+(@pxref{Creating Symbols}):
+
address@hidden
+emacs_value fintern = env->intern (env, "intern");
+emacs_value sym_name =
+  env->make_string (env, name_str, strlen (name_str));
+emacs_value intern_args[] = @{ sym_name, env->intern (env, "nil") @};
+emacs_value symbol = env->funcall (env, fintern, 2, intern_args);
address@hidden example
+
address@hidden deftypefn
+
address@hidden Function emacs_value funcall (emacs_env address@hidden, 
emacs_value @var{func}, ptrdiff_t @var{nargs}, emacs_value address@hidden)
+This function calls the specified @var{func} passing it @var{nargs}
+arguments from the array pointed to by @var{args}.  The argument
address@hidden can be a function symbol (e.g., returned by @code{intern}
+described above), a module function returned by @code{make_function}
+(@pxref{Module Functions}), a subroutine written in C, etc.  If
address@hidden is zero, @var{args} can be a @code{NULL} pointer.
+
+The function returns the value that @var{func} returned.
address@hidden deftypefn
+
+If your module includes potentially long-running code, it is a good
+idea to check from time to time in that code whether the user wants to
+quit, e.g., by typing @kbd{C-g} (@pxref{Quitting}).  The following
+function, which is available since Emacs 26.1, is provided for that
+purpose.
+
address@hidden
address@hidden Function bool should_quit (emacs_env address@hidden)
+This function returns @code{true} if the user wants to quit.  In that
+case, we recommend that your module function aborts any on-going
+processing and returns as soon as possible.
address@hidden deftypefn
+
address@hidden Module Nonlocal
address@hidden Nonlocal Exits in Modules
address@hidden nonlocal exits, in modules
+
+  Emacs Lisp supports nonlocal exits, whereby program control is
+transfered from one point in a program to another remote point.
address@hidden Exits}.  Thus, Lisp functions called by your module
+might exit nonlocally by calling @code{signal} or @code{throw}, and
+your module functions must handle such nonlocal exits properly.  Such
+handling is needed because C programs will not automatically release
+resources and perform other cleanups in these cases; your module code
+must itself do it.  The module @acronym{API} provides facilities for
+that, described in this subsection.  They are generally available
+since Emacs 25; those of them that became available in later releases
+explicitly call out the first Emacs version where they became part of
+the @acronym{API}.
+
+When some Lisp code called by a module function signals an error or
+throws, the nonlocal exit is trapped, and the pending exit and its
+associated data are stored in the environment.  Whenever a nonlocal
+exit is pending in the environment, any module @acronym{API} function
+called with a pointer to that environment will return immediately
+without any processing (the functions @code{non_local_exit_check},
address@hidden, and @code{non_local_exit_clear} are
+exceptions from this rule).  If your module function then does nothing
+and returns to Emacs, a pending nonlocal exit will cause Emacs to act
+on it: signal an error or throw to the corresponding @code{catch}.
+
+So the simplest ``handling'' of nonlocal exits in module functions is
+to do nothing special and let the rest of your code to run as if
+nothing happened.  However, this can cause two classes of problems:
+
address@hidden @minus
address@hidden
+Your module function might use uninitialized or undefined values,
+since @acronym{API} functions return immediately without producing the
+expected results.
+
address@hidden
+Your module might leak resources, because it might not have the
+opportunity to release them.
address@hidden itemize
+
+Therefore, we recommend that your module functions check for nonlocal
+exit conditions and recover from them, using the functions described
+below.
+
address@hidden Function enum emacs_funcall_exit non_local_exit_check (emacs_env 
address@hidden)
+This function returns the kind of nonlocal exit condition stored in
address@hidden  The possible values are:
+
address@hidden address@hidden, enumeration}
address@hidden @code
address@hidden emacs_funcall_exit_return
+The last @acronym{API} function exited normally.
address@hidden emacs_funcall_exit_signal
+The last @acronym{API} function signaled an error.
address@hidden emacs_funcall_exit_throw
+The last @acronym{API} function exited via @code{throw}.
address@hidden vtable
address@hidden deftypefn
+
address@hidden Function emacs_funcall_exit non_local_exit_get (emacs_env 
address@hidden, emacs_value address@hidden, emacs_value address@hidden)
+This function returns the kind of nonlocal exit condition stored in
address@hidden, like @code{non_local_exit_check} does, but it also returns
+the full information about the nonlocal exit, if any.  If the return
+value is @code{emacs_funcall_exit_signal}, the function stores the
+error symbol in @address@hidden and the error data in
address@hidden@var{data}} (@pxref{Signaling Errors}).  If the return value is
address@hidden, the function stores the @code{catch}
+tag symbol in @address@hidden and the @code{throw} value in
address@hidden@var{data}}.  The function doesn't store anything in memory
+pointed by these arguments when the return value is
address@hidden
address@hidden deftypefn
+
+You should check nonlocal exit conditions where it matters: before you
+allocated some resource or after you allocated a resource that might
+need freeing, or where a failure means further processing is
+impossible or infeasible.
+
+Once your module function detected that a nonlocal exit is pending, it
+can either return to Emacs (after performing the necessary local
+cleanup), or it can attempt to recover from the nonlocal exit.  The
+following @acronym{API} functions will help with these tasks.
+
address@hidden Function void non_local_exit_clear (emacs_env address@hidden)
+This function clears the pending nonlocal exit conditions and data
+from @var{env}.  After calling it, the module @acronym{API} functions
+will work normally.  Use this function if your module function can
+recover from nonlocal exits of the Lisp functions it calls and
+continue, and also before calling any of the following two functions
+(or any other @acronym{API} functions, if you want them to perform
+their intended processing when a nonlocal exit is pending).
address@hidden deftypefn
+
address@hidden Function void non_local_exit_throw (emacs_env address@hidden, 
emacs_value @var{tag}, emacs_value @var{value})
+This function throws to the Lisp @code{catch} symbol represented by
address@hidden, passing it @var{value} as the value to return.  Your module
+function should in general return soon after calling this function.
+One use of this function is when you want to re-throw a non-local exit
+from one of the called @acronym{API} or Lisp functions.
address@hidden deftypefn
+
address@hidden Function void non_local_exit_signal (emacs_env address@hidden, 
emacs_value @var{error}, emacs_value @var{data})
+This function signals the error represented by @var{error} with the
+specified error data @var{data}.  The module function should return
+soon after calling this function.  This function could be useful,
+e.g., for signaling errors from module functions to Emacs.
address@hidden deftypefn
+
+
 @node Object Internals
 @section Object Internals
 @cindex object internals
diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi
index 80b7572..cbb2f70 100644
--- a/doc/lispref/loading.texi
+++ b/doc/lispref/loading.texi
@@ -1139,8 +1139,6 @@ Features}).
 @section Emacs Dynamic Modules
 @cindex dynamic modules
 
address@hidden FIXME: This is intentionally incomplete, as the module 
integration
address@hidden is not yet finished.  To be refined later.
   A @dfn{dynamic Emacs module} is a shared library that provides
 additional functionality for use in Emacs Lisp programs, just like a
 package written in Emacs Lisp would.
@@ -1162,30 +1160,43 @@ Every dynamic module should export a C-callable 
function named
 @code{load} or @code{require} which loads the module.  It should also
 export a symbol named @code{plugin_is_GPL_compatible} to indicate that
 its code is released under the GPL or compatible license; Emacs will
-refuse to load modules that don't export such a symbol.
+signal an error if your program tries to load modules that don't
+export such a symbol.
 
 If a module needs to call Emacs functions, it should do so through the
-API defined and documented in the header file @file{emacs-module.h}
-that is part of the Emacs distribution.
address@hidden (Application Programming Interface) defined and
+documented in the header file @file{emacs-module.h} that is part of
+the Emacs distribution.  @xref{Writing Dynamic Modules}, for details
+of using that API when writing your own modules.
 
 @cindex user-ptr object
address@hidden user pointer object
 Modules can create @code{user-ptr} Lisp objects that embed pointers to
 C struct's defined by the module.  This is useful for keeping around
 complex data structures created by a module, to be passed back to the
 module's functions.  User-ptr objects can also have associated
 @dfn{finalizers} -- functions to be run when the object is GC'ed; this
 is useful for freeing any resources allocated for the underlying data
-structure, such as memory, open file descriptors, etc.
+structure, such as memory, open file descriptors, etc.  @xref{Module
+Values}.
 
 @defun user-ptrp object
 This function returns @code{t} if its argument is a @code{user-ptr}
 object.
 @end defun
 
address@hidden module-load file
+Emacs calls this low-level primitive to load a module from the
+specified @var{file} and perform the necessary initialization of the
+module.  This is the primitive which makes sure the module exports the
address@hidden symbol, calls the module's
address@hidden function, and signals an error if that
+function returns an error indication, or if the use typed @kbd{C-g}
+during the initialization.  If the initialization succeeds,
address@hidden returns @code{t}.  Note that @var{file} must
+already have the proper file-name extension, as this function doesn't
+try looking for files with known extensions, unlike @code{load}.
address@hidden defun
+
 Loadable modules in Emacs are enabled by using the
 @kbd{--with-modules} option at configure time.
-
-If you write your own dynamic modules, you may wish to verify their
-conformance to the Emacs dynamic module API.  Invoking Emacs with the
address@hidden option will help you in this matter.
address@hidden Options,,,emacs, The GNU Emacs Manual}.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]