diff options
Diffstat (limited to 'devdocs/elisp/module-nonlocal.html')
| -rw-r--r-- | devdocs/elisp/module-nonlocal.html | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/devdocs/elisp/module-nonlocal.html b/devdocs/elisp/module-nonlocal.html new file mode 100644 index 00000000..cc969cde --- /dev/null +++ b/devdocs/elisp/module-nonlocal.html @@ -0,0 +1,22 @@ + <h4 class="subsection"> Nonlocal Exits in Modules</h4> <p>Emacs Lisp supports nonlocal exits, whereby program control is transferred from one point in a program to another remote point. See <a href="nonlocal-exits">Nonlocal Exits</a>. Thus, Lisp functions called by your module might exit nonlocally by calling <code>signal</code> or <code>throw</code>, 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</acronym> 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</acronym>. </p> <p>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</acronym> function called with a pointer to that environment will return immediately without any processing (the functions <code>non_local_exit_check</code>, <code>non_local_exit_get</code>, and <code>non_local_exit_clear</code> 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</code>. </p> <p>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: </p> <ul class="no-bullet"> <li>- Your module function might use uninitialized or undefined values, since <acronym>API</acronym> functions return immediately without producing the expected results. </li> +<li>- Your module might leak resources, because it might not have the opportunity to release them. </li> +</ul> <p>Therefore, we recommend that your module functions check for nonlocal exit conditions and recover from them, using the functions described below. </p> <dl> <dt id="non_local_exit_check">Function: <em>enum emacs_funcall_exit</em> <strong>non_local_exit_check</strong> <em>(emacs_env *<var>env</var>)</em> +</dt> <dd> +<p>This function returns the kind of nonlocal exit condition stored in <var>env</var>. The possible values are: </p> <dl compact> <dt> +<code>emacs_funcall_exit_return</code> </dt> <dd><p>The last <acronym>API</acronym> function exited normally. </p></dd> <dt> +<code>emacs_funcall_exit_signal</code> </dt> <dd><p>The last <acronym>API</acronym> function signaled an error. </p></dd> <dt> +<code>emacs_funcall_exit_throw</code> </dt> <dd><p>The last <acronym>API</acronym> function exited via <code>throw</code>. </p></dd> </dl> </dd> +</dl> <dl> <dt id="non_local_exit_get">Function: <em>enum emacs_funcall_exit</em> <strong>non_local_exit_get</strong> <em>(emacs_env *<var>env</var>, emacs_value *<var>symbol</var>, emacs_value *<var>data</var>)</em> +</dt> <dd><p>This function returns the kind of nonlocal exit condition stored in <var>env</var>, like <code>non_local_exit_check</code> does, but it also returns the full information about the nonlocal exit, if any. If the return value is <code>emacs_funcall_exit_signal</code>, the function stores the error symbol in <code>*<var>symbol</var></code> and the error data in <code>*<var>data</var></code> (see <a href="signaling-errors">Signaling Errors</a>). If the return value is <code>emacs_funcall_exit_throw</code>, the function stores the <code>catch</code> tag symbol in <code>*<var>symbol</var></code> and the <code>throw</code> value in <code>*<var>data</var></code>. The function doesn’t store anything in memory pointed by these arguments when the return value is <code>emacs_funcall_exit_return</code>. </p></dd> +</dl> <p>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. </p> <p>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</acronym> functions will help with these tasks. </p> <dl> <dt id="non_local_exit_clear">Function: <em>void</em> <strong>non_local_exit_clear</strong> <em>(emacs_env *<var>env</var>)</em> +</dt> <dd><p>This function clears the pending nonlocal exit conditions and data from <var>env</var>. After calling it, the module <acronym>API</acronym> 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</acronym> functions, if you want them to perform their intended processing when a nonlocal exit is pending). </p></dd> +</dl> <dl> <dt id="non_local_exit_throw">Function: <em>void</em> <strong>non_local_exit_throw</strong> <em>(emacs_env *<var>env</var>, emacs_value <var>tag</var>, emacs_value <var>value</var>)</em> +</dt> <dd><p>This function throws to the Lisp <code>catch</code> symbol represented by <var>tag</var>, passing it <var>value</var> 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</acronym> or Lisp functions. </p></dd> +</dl> <dl> <dt id="non_local_exit_signal">Function: <em>void</em> <strong>non_local_exit_signal</strong> <em>(emacs_env *<var>env</var>, emacs_value <var>symbol</var>, emacs_value <var>data</var>)</em> +</dt> <dd><p>This function signals the error represented by the error symbol <var>symbol</var> with the specified error data <var>data</var>. 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. </p></dd> +</dl><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-Nonlocal.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/Module-Nonlocal.html</a> + </p> +</div> |
