diff options
Diffstat (limited to 'devdocs/elisp/module-values.html')
| -rw-r--r-- | devdocs/elisp/module-values.html | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/devdocs/elisp/module-values.html b/devdocs/elisp/module-values.html new file mode 100644 index 00000000..c3f0e46f --- /dev/null +++ b/devdocs/elisp/module-values.html @@ -0,0 +1,171 @@ + <h4 class="subsection"> Conversion Between Lisp and Module Values</h4> <p>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 <acronym>API</acronym> provides the <code>emacs_value</code> type, which represents Emacs Lisp objects communicated via the <acronym>API</acronym>; it is the functional equivalent of the <code>Lisp_Object</code> type used in Emacs C primitives (see <a href="writing-emacs-primitives">Writing Emacs Primitives</a>). This section describes the parts of the module <acronym>API</acronym> that allow to create <code>emacs_value</code> objects corresponding to basic Lisp data types, and how to access from C data in <code>emacs_value</code> objects that correspond to Lisp objects. </p> <p>All of the functions described below are actually <em>function pointers</em> 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: </p> <div class="example"> <pre class="example">emacs_env *env; /* the environment pointer */ +env->some_function (arguments…); +</pre> +</div> <p>The <code>emacs_env</code> pointer will usually come from the first argument to the module function, or from the call to <code>get_environment</code> if you need the environment in the module initialization function. </p> <p>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. </p> <p>The following <acronym>API</acronym> functions extract values of various C data types from <code>emacs_value</code> objects. They all raise the <code>wrong-type-argument</code> error condition (see <a href="type-predicates">Type Predicates</a>) if the argument <code>emacs_value</code> object is not of the type expected by the function. See <a href="module-nonlocal">Module Nonlocal</a>, 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 <acronym>API</acronym> function <code>type_of</code> (see <a href="module-misc">type_of</a>) can be used to obtain the type of a <code>emacs_value</code> object. </p> <dl> <dt id="extract_integer">Function: <em>intmax_t</em> <strong>extract_integer</strong> <em>(emacs_env *<var>env</var>, emacs_value <var>arg</var>)</em> +</dt> <dd><p>This function returns the value of a Lisp integer specified by <var>arg</var>. The C data type of the return value, <code>intmax_t</code>, is the widest integer data type supported by the C compiler, typically <code>long long</code>. If the value of <var>arg</var> doesn’t fit into an <code>intmax_t</code>, the function signals an error using the error symbol <code>overflow-error</code>. </p></dd> +</dl> <dl> <dt id="extract_big_integer">Function: <em>bool</em> <strong>extract_big_integer</strong> <em>(emacs_env *<var>env</var>, emacs_value <var>arg</var>, int *<var>sign</var>, ptrdiff_t *<var>count</var>, emacs_limb_t *<var>magnitude</var>)</em> +</dt> <dd> +<p>This function, which is available since Emacs 27, extracts the integer value of <var>arg</var>. The value of <var>arg</var> must be an integer (fixnum or bignum). If <var>sign</var> is not <code>NULL</code>, it stores the sign of <var>arg</var> (-1, 0, or +1) into <code>*sign</code>. The magnitude is stored into <var>magnitude</var> as follows. If <var>count</var> and <var>magnitude</var> are both non-<code>NULL</code>, then <var>magnitude</var> must point to an array of at least <code>*count</code> <code>unsigned long</code> elements. If <var>magnitude</var> is large enough to hold the magnitude of <var>arg</var>, then this function writes the magnitude into the <var>magnitude</var> array in little-endian form, stores the number of array elements written into <code>*count</code>, and returns <code>true</code>. If <var>magnitude</var> is not large enough, it stores the required array size into <code>*count</code>, signals an error, and returns <code>false</code>. If <var>count</var> is not <code>NULL</code> and <var>magnitude</var> is <code>NULL</code>, then the function stores the required array size into <code>*count</code> and returns <code>true</code>. </p> <p>Emacs guarantees that the maximum required value of <code>*count</code> never exceeds <code>min (PTRDIFF_MAX, SIZE_MAX) / sizeof +(emacs_limb_t)</code>, so you can use <code>malloc (*count * sizeof *magnitude)</code> to allocate the <code>magnitude</code> array without worrying about integer overflow in the size calculation. </p> +</dd> +</dl> <dl> <dt id="emacs_limb_t">Type alias: <strong>emacs_limb_t</strong> +</dt> <dd><p>This is an unsigned integer type, used as the element type for the magnitude arrays for the big integer conversion functions. The type is guaranteed to have unique object representations, i.e., no padding bits. </p></dd> +</dl> <dl> <dt id="EMACS_LIMB_MAX">Macro: <strong>EMACS_LIMB_MAX</strong> +</dt> <dd><p>This macro expands to a constant expression specifying the maximum possible value for an <code>emacs_limb_t</code> object. The expression is suitable for use in <code>#if</code>. </p></dd> +</dl> <dl> <dt id="extract_float">Function: <em>double</em> <strong>extract_float</strong> <em>(emacs_env *<var>env</var>, emacs_value <var>arg</var>)</em> +</dt> <dd><p>This function returns the value of a Lisp float specified by <var>arg</var>, as a C <code>double</code> value. </p></dd> +</dl> <dl> <dt id="extract_time">Function: <em>struct timespec</em> <strong>extract_time</strong> <em>(emacs_env *<var>env</var>, emacs_value <var>arg</var>)</em> +</dt> <dd> +<p>This function, which is available since Emacs 27, interprets <var>arg</var> as an Emacs Lisp time value and returns the corresponding <code>struct +timespec</code>. See <a href="time-of-day">Time of Day</a>. <code>struct timespec</code> represents a timestamp with nanosecond precision. It has the following members: </p> <dl compact> <dt><code>time_t tv_sec</code></dt> <dd><p>Whole number of seconds. </p></dd> <dt><code>long tv_nsec</code></dt> <dd><p>Fractional seconds as a number of nanoseconds. For timestamps returned by <code>extract_time</code>, this is always nonnegative and less than one billion. (Although POSIX requires the type of <code>tv_nsec</code> to be <code>long</code>, the type is <code>long long</code> on some nonstandard platforms.) </p></dd> </dl> <p>See <a href="https://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html#Elapsed-Time">(libc)Elapsed Time</a>. </p> <p>If <var>time</var> has higher precision than nanoseconds, then this function truncates it to nanosecond precision towards negative infinity. This function signals an error if <var>time</var> (truncated to nanoseconds) cannot be represented by <code>struct timespec</code>. For example, if <code>time_t</code> is a 32-bit integer type, then a <var>time</var> value of ten billion seconds would signal an error, but a <var>time</var> value of 600 picoseconds would get truncated to zero. </p> <p>If you need to deal with time values that are not representable by <code>struct timespec</code>, or if you want higher precision, call the Lisp function <code>encode-time</code> and work with its return value. See <a href="time-conversion">Time Conversion</a>. </p> +</dd> +</dl> <dl> <dt id="copy_string_contents">Function: <em>bool</em> <strong>copy_string_contents</strong> <em>(emacs_env *<var>env</var>, emacs_value <var>arg</var>, char *<var>buf</var>, ptrdiff_t *<var>len</var>)</em> +</dt> <dd> +<p>This function stores the UTF-8 encoded text of a Lisp string specified by <var>arg</var> in the array of <code>char</code> pointed by <var>buf</var>, which should have enough space to hold at least <code>*<var>len</var></code> bytes, including the terminating null byte. The argument <var>len</var> must not be a <code>NULL</code> pointer, and, when the function is called, it should point to a value that specifies the size of <var>buf</var> in bytes. </p> <p>If the buffer size specified by <code>*<var>len</var></code> is large enough to hold the string’s text, the function stores in <code>*<var>len</var></code> the actual number of bytes copied to <var>buf</var>, including the terminating null byte, and returns <code>true</code>. If the buffer is too small, the function raises the <code>args-out-of-range</code> error condition, stores the required number of bytes in <code>*<var>len</var></code>, and returns <code>false</code>. See <a href="module-nonlocal">Module Nonlocal</a>, for how to handle pending error conditions. </p> <p>The argument <var>buf</var> can be a <code>NULL</code> pointer, in which case the function stores in <code>*<var>len</var></code> the number of bytes required for storing the contents of <var>arg</var>, and returns <code>true</code>. This is how you can determine the size of <var>buf</var> needed to store a particular string: first call <code>copy_string_contents</code> with <code>NULL</code> as <var>buf</var>, then allocate enough memory to hold the number of bytes stored by the function in <code>*<var>len</var></code>, and call the function again with non-<code>NULL</code> <var>buf</var> to actually perform the text copying. </p> +</dd> +</dl> <dl> <dt id="vec_get">Function: <em>emacs_value</em> <strong>vec_get</strong> <em>(emacs_env *<var>env</var>, emacs_value <var>vector</var>, ptrdiff_t <var>index</var>)</em> +</dt> <dd><p>This function returns the element of <var>vector</var> at <var>index</var>. The <var>index</var> of the first vector element is zero. The function raises the <code>args-out-of-range</code> error condition if the value of <var>index</var> 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. </p></dd> +</dl> <dl> <dt id="vec_size">Function: <em>ptrdiff_t</em> <strong>vec_size</strong> <em>(emacs_env *<var>env</var>, emacs_value <var>vector</var>)</em> +</dt> <dd><p>This function returns the number of elements in <var>vector</var>. </p></dd> +</dl> <dl> <dt id="vec_set">Function: <em>void</em> <strong>vec_set</strong> <em>(emacs_env *<var>env</var>, emacs_value <var>vector</var>, ptrdiff_t <var>index</var>, emacs_value <var>value</var>)</em> +</dt> <dd><p>This function stores <var>value</var> in the element of <var>vector</var> whose index is <var>index</var>. It raises the <code>args-out-of-range</code> error condition if the value of <var>index</var> is invalid. </p></dd> +</dl> <p>The following <acronym>API</acronym> functions create <code>emacs_value</code> objects from basic C data types. They all return the created <code>emacs_value</code> object. </p> <dl> <dt id="make_integer">Function: <em>emacs_value</em> <strong>make_integer</strong> <em>(emacs_env *<var>env</var>, intmax_t <var>n</var>)</em> +</dt> <dd><p>This function takes an integer argument <var>n</var> and returns the corresponding <code>emacs_value</code> object. It returns either a fixnum or a bignum depending on whether the value of <var>n</var> is inside the limits set by <code>most-negative-fixnum</code> and <code>most-positive-fixnum</code> (see <a href="integer-basics">Integer Basics</a>). </p></dd> +</dl> <dl> <dt id="make_big_integer">Function: <em>emacs_value</em> <strong>make_big_integer</strong> <em>(emacs_env *<var>env</var>, int sign, ptrdiff_t count, const emacs_limb_t *magnitude)</em> +</dt> <dd><p>This function, which is available since Emacs 27, takes an arbitrary-sized integer argument and returns a corresponding <code>emacs_value</code> object. The <var>sign</var> argument gives the sign of the return value. If <var>sign</var> is nonzero, then <var>magnitude</var> must point to an array of at least <var>count</var> elements specifying the little-endian magnitude of the return value. </p></dd> +</dl> <p>The following example uses the GNU Multiprecision Library (GMP) to calculate the next probable prime after a given integer. See <a href="https://www.gmplib.org/manual/index.html#Top">(gmp)Top</a>, for a general overview of GMP, and see <a href="https://www.gmplib.org/manual/Integer-Import-and-Export.html#Integer-Import-and-Export">(gmp)Integer Import and Export</a> for how to convert the <code>magnitude</code> array to and from GMP <code>mpz_t</code> values. </p> <div class="example"> <pre class="example">#include <emacs-module.h> +int plugin_is_GPL_compatible; + +#include <assert.h> +#include <limits.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> + +#include <gmp.h> + +static void +memory_full (emacs_env *env) +{ + static const char message[] = "Memory exhausted"; + emacs_value data = env->make_string (env, message, + strlen (message)); + env->non_local_exit_signal + (env, env->intern (env, "error"), + env->funcall (env, env->intern (env, "list"), 1, &data)); +} + +enum +{ + order = -1, endian = 0, nails = 0, + limb_size = sizeof (emacs_limb_t), + max_nlimbs = ((SIZE_MAX < PTRDIFF_MAX ? SIZE_MAX : PTRDIFF_MAX) + / limb_size) +}; + +static bool +extract_big_integer (emacs_env *env, emacs_value arg, mpz_t result) +{ + ptrdiff_t nlimbs; + bool ok = env->extract_big_integer (env, arg, NULL, &nlimbs, NULL); + if (!ok) + return false; + assert (0 < nlimbs && nlimbs <= max_nlimbs); + emacs_limb_t *magnitude = malloc (nlimbs * limb_size); + if (magnitude == NULL) + { + memory_full (env); + return false; + } + int sign; + ok = env->extract_big_integer (env, arg, &sign, &nlimbs, magnitude); + assert (ok); + mpz_import (result, nlimbs, order, limb_size, endian, nails, magnitude); + free (magnitude); + if (sign < 0) + mpz_neg (result, result); + return true; +} + +static emacs_value +make_big_integer (emacs_env *env, const mpz_t value) +{ + size_t nbits = mpz_sizeinbase (value, 2); + int bitsperlimb = CHAR_BIT * limb_size - nails; + size_t nlimbs = nbits / bitsperlimb + (nbits % bitsperlimb != 0); + emacs_limb_t *magnitude + = nlimbs <= max_nlimbs ? malloc (nlimbs * limb_size) : NULL; + if (magnitude == NULL) + { + memory_full (env); + return NULL; + } + size_t written; + mpz_export (magnitude, &written, order, limb_size, endian, nails, value); + assert (written == nlimbs); + assert (nlimbs <= PTRDIFF_MAX); + emacs_value result = env->make_big_integer (env, mpz_sgn (value), + nlimbs, magnitude); + free (magnitude); + return result; +} + +static emacs_value +next_prime (emacs_env *env, ptrdiff_t nargs, emacs_value *args, + void *data) +{ + assert (nargs == 1); + mpz_t p; + mpz_init (p); + extract_big_integer (env, args[0], p); + mpz_nextprime (p, p); + emacs_value result = make_big_integer (env, p); + mpz_clear (p); + return result; +} + +int +emacs_module_init (struct emacs_runtime *runtime) +{ + emacs_env *env = runtime->get_environment (runtime); + emacs_value symbol = env->intern (env, "next-prime"); + emacs_value func + = env->make_function (env, 1, 1, next_prime, NULL, NULL); + emacs_value args[] = {symbol, func}; + env->funcall (env, env->intern (env, "defalias"), 2, args); + return 0; +} +</pre> +</div> <dl> <dt id="make_float">Function: <em>emacs_value</em> <strong>make_float</strong> <em>(emacs_env *<var>env</var>, double <var>d</var>)</em> +</dt> <dd><p>This function takes a <code>double</code> argument <var>d</var> and returns the corresponding Emacs floating-point value. </p></dd> +</dl> <dl> <dt id="make_time">Function: <em>emacs_value</em> <strong>make_time</strong> <em>(emacs_env *<var>env</var>, struct timespec <var>time</var>)</em> +</dt> <dd><p>This function, which is available since Emacs 27, takes a <code>struct +timespec</code> argument <var>time</var> and returns the corresponding Emacs timestamp as a pair <code>(<var>ticks</var> . <var>hz</var>)</code>. See <a href="time-of-day">Time of Day</a>. The return value represents exactly the same timestamp as <var>time</var>: all input values are representable, and there is never a loss of precision. <code><var>time</var>.tv_sec</code> and <code><var>time</var>.tv_nsec</code> can be arbitrary values. In particular, there’s no requirement that <var>time</var> be normalized. This means that <code><var>time</var>.tv_nsec</code> can be negative or larger than 999,999,999. </p></dd> +</dl> <dl> <dt id="make_string">Function: <em>emacs_value</em> <strong>make_string</strong> <em>(emacs_env *<var>env</var>, const char *<var>str</var>, ptrdiff_t <var>len</var>)</em> +</dt> <dd><p>This function creates an Emacs string from C text string pointed by <var>str</var> whose length in bytes, not including the terminating null byte, is <var>len</var>. The original string in <var>str</var> can be either an <acronym>ASCII</acronym> string or a UTF-8 encoded non-<acronym>ASCII</acronym> string; it can include embedded null bytes, and doesn’t have to end in a terminating null byte at <code><var>str</var>[<var>len</var>]</code>. The function raises the <code>overflow-error</code> error condition if <var>len</var> is negative or exceeds the maximum length of an Emacs string. If <var>len</var> is zero, then <var>str</var> can be <code>NULL</code>, otherwise it must point to valid memory. For nonzero <var>len</var>, <code>make_string</code> returns unique mutable string objects. </p></dd> +</dl> <dl> <dt id="make_unibyte_string">Function: <em>emacs_value</em> <strong>make_unibyte_string</strong> <em>(emacs_env *<var>env</var>, const char *<var>str</var>, ptrdiff_t <var>len</var>)</em> +</dt> <dd><p>This function is like <code>make_string</code>, but has no restrictions on the values of the bytes in the C string, and can be used to pass binary data to Emacs in the form of a unibyte string. </p></dd> +</dl> <p>The <acronym>API</acronym> does not provide functions to manipulate Lisp data structures, for example, create lists with <code>cons</code> and <code>list</code> (see <a href="building-lists">Building Lists</a>), extract list members with <code>car</code> and <code>cdr</code> (see <a href="list-elements">List Elements</a>), create vectors with <code>vector</code> (see <a href="vector-functions">Vector Functions</a>), etc. For these, use <code>intern</code> and <code>funcall</code>, described in the next subsection, to call the corresponding Lisp functions. </p> <p>Normally, <code>emacs_value</code> objects have a rather short lifetime: it ends when the <code>emacs_env</code> pointer used for their creation goes out of scope. Occasionally, you may need to create <em>global references</em>: <code>emacs_value</code> objects that live as long as you wish. Use the following two functions to manage such objects. </p> <dl> <dt id="make_global_ref">Function: <em>emacs_value</em> <strong>make_global_ref</strong> <em>(emacs_env *<var>env</var>, emacs_value <var>value</var>)</em> +</dt> <dd><p>This function returns a global reference for <var>value</var>. </p></dd> +</dl> <dl> <dt id="free_global_ref">Function: <em>void</em> <strong>free_global_ref</strong> <em>(emacs_env *<var>env</var>, emacs_value <var>global_value</var>)</em> +</dt> <dd><p>This function frees the <var>global_value</var> previously created by <code>make_global_ref</code>. The <var>global_value</var> is no longer valid after the call. Your module code should pair each call to <code>make_global_ref</code> with the corresponding <code>free_global_ref</code>. </p></dd> +</dl> <p>An alternative to keeping around C data structures that need to be passed to module functions later is to create <em>user pointer</em> objects. A user pointer, or <code>user-ptr</code>, 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 (see <a href="garbage-collection">Garbage Collection</a>). The module <acronym>API</acronym> provides functions to create and access <code>user-ptr</code> objects. These functions raise the <code>wrong-type-argument</code> error condition if they are called on <code>emacs_value</code> that doesn’t represent a <code>user-ptr</code> object. </p> <dl> <dt id="make_user_ptr">Function: <em>emacs_value</em> <strong>make_user_ptr</strong> <em>(emacs_env *<var>env</var>, emacs_finalizer <var>fin</var>, void *<var>ptr</var>)</em> +</dt> <dd> +<p>This function creates and returns a <code>user-ptr</code> object which wraps the C pointer <var>ptr</var>. The finalizer function <var>fin</var> can be a <code>NULL</code> pointer (meaning no finalizer), or it can be a function of the following signature: </p> <div class="example"> <pre class="example">typedef void (*emacs_finalizer) (void *<var>ptr</var>); +</pre> +</div> <p>If <var>fin</var> is not a <code>NULL</code> pointer, it will be called with the <var>ptr</var> as the argument when the <code>user-ptr</code> object is garbage-collected. Don’t run any expensive code in a finalizer, because GC must finish quickly to keep Emacs responsive. </p> +</dd> +</dl> <dl> <dt id="get_user_ptr">Function: <em>void *</em> <strong>get_user_ptr</strong> <em>(emacs_env *<var>env</var>, emacs_value <var>arg</var>)</em> +</dt> <dd><p>This function extracts the C pointer from the Lisp object represented by <var>arg</var>. </p></dd> +</dl> <dl> <dt id="set_user_ptr">Function: <em>void</em> <strong>set_user_ptr</strong> <em>(emacs_env *<var>env</var>, emacs_value <var>arg</var>, void *<var>ptr</var>)</em> +</dt> <dd><p>This function sets the C pointer embedded in the <code>user-ptr</code> object represented by <var>arg</var> to <var>ptr</var>. </p></dd> +</dl> <dl> <dt id="get_user_finalizer">Function: <em>emacs_finalizer</em> <strong>get_user_finalizer</strong> <em>(emacs_env *<var>env</var>, emacs_value <var>arg</var>)</em> +</dt> <dd><p>This function returns the finalizer of the <code>user-ptr</code> object represented by <var>arg</var>, or <code>NULL</code> if it doesn’t have a finalizer. </p></dd> +</dl> <dl> <dt id="set_user_finalizer">Function: <em>void</em> <strong>set_user_finalizer</strong> <em>(emacs_env *<var>env</var>, emacs_value <var>arg</var>, emacs_finalizer <var>fin</var>)</em> +</dt> <dd><p>This function changes the finalizer of the <code>user-ptr</code> object represented by <var>arg</var> to be <var>fin</var>. If <var>fin</var> is a <code>NULL</code> pointer, the <code>user-ptr</code> object will have no finalizer. </p></dd> +</dl> <p>Note that the <code>emacs_finalizer</code> type works for both user pointer an module function finalizers. See <a href="module-functions#Module-Function-Finalizers">Module Function Finalizers</a>. </p><div class="_attribution"> + <p class="_attribution-p"> + Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc. <br>Licensed under the GNU GPL license.<br> + <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Module-Values.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/Module-Values.html</a> + </p> +</div> |
