1
0
Fork 0
cl-sites/ecl.common-lisp.dev/static/manual/Embedding-ECL.html

554 lines
31 KiB
HTML
Raw Permalink Normal View History

2024-12-24 19:15:49 +01:00
<!DOCTYPE html>
<html>
<!-- Created by GNU Texinfo 7.0.3, https://www.gnu.org/software/texinfo/ -->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Embedding ECL (ECL Manual)</title>
<meta name="description" content="Embedding ECL (ECL Manual)">
<meta name="keywords" content="Embedding ECL (ECL Manual)">
<meta name="resource-type" content="document">
<meta name="distribution" content="global">
<meta name="Generator" content="makeinfo">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="index.html" rel="start" title="Top">
<link href="Indexes.html" rel="index" title="Indexes">
<link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
<link href="User_0027s-guide.html" rel="up" title="User's guide">
<link href="The-break-loop.html" rel="prev" title="The break loop">
<style type="text/css">
<!--
/* colors */
a.copiable-link {visibility: hidden; text-decoration: none; line-height: 0em}
div.example {margin-left: 3.2em}
span.r {font-family: initial; font-weight: normal; font-style: normal}
span:hover a.copiable-link {visibility: visible}
strong.def-name {font-family: monospace; font-weight: bold; font-size: larger}
ul.mark-bullet {list-style-type: disc}
@media (prefers-color-scheme: dark) {
/* dark theme */
html { color: seashell;
background: #1A1A1A; }
body { background: #1A1A1A; }
th { border-bottom: 2px solid lightgray; }
h1, h2, h3, h4, h5 { background-image: linear-gradient(to left, #202020, #3A3A3A); }
code, var, code a { color: darkorange;
background: #2A2A2A; }
a { color: seashell; }
pre { background: #2A2A2A;
color: seashell;
/* mark longer code block with stripe on the left */
border-left: 5px solid darkorange;
padding-left: 10px; }
pre.screen { background: #2A2A2A;
border: 1px solid lightgray; }
pre.programlisting { background: #2A2A2A;
border-left: 1px solid lightgray;
border-top: 1px solid lightgray; }
/* we need a light background in order for the images to be readable */
img { background: white }
}
@media (prefers-color-scheme: light) {
/* light theme */
html { background: white }
body { background: white }
th { border-bottom: 2px solid gray; }
h1, h2, h3, h4, h5 { background: lightgray; }
code, var, code a { color: darkred;
background: whitesmoke; }
a { color: #000; }
pre { background: whitesmoke;
color: black;
/* mark longer code block with stripe on the left */
border-left: 5px solid darkred;
padding-left: 10px; }
pre.screen { background: #EEE;
border: 1px solid black; }
pre.programlisting { background: #EEEEEE;
border-left: 1px solid black;
border-top: 1px solid black; }
}
body {
margin: 1em 125px 0 10%;
line-height: 1.5em;
padding: 0 2em 1em 2em;
font: 13px Verdana,Arial, sans-serif
}
ul, dd, dl, dt { margin-top: 0; margin-bottom: 0; }
p, code, td, dl, dt {
line-height: 1.5em;
}
table {
font: inherit;
border-collapse: collapse;
}
th, td {
vertical-align: top;
}
h1, h2, h3 { padding-left: 15px; }
h4, h5 { padding-left: 5px; }
code, pre {
font-size: 1em;
font-family: monospace;
}
var {
font-size: 1em;
}
/* links inside code appear the same as the code itself */
code a {
font-weight: normal;
text-decoration: none;
}
/* but get an underline when hovering */
code a:hover {
text-decoration: underline;
}
/* ordinary links appear in bold */
a { font-weight: bold; }
pre.verbatim {
margin: 0 0 0 0;
}
pre {
overflow: auto;
}
pre.screen {
font-weight: bold;
padding: 0.5em;
}
pre.programlisting {
padding: 0.5em;
}
div p { padding: 0 2em }
li p { padding: 0; margin: 0 }
hr { display: none; }
div.funcsynopsis p {
text-indent: -2em;
}
div.variablelist {
padding: 0 2em;
}
.type, .funcsynopsis, .symbol {
font-family: monospace;
}
.type, .symbol, .replaceable {
white-space: nowrap;
}
-->
</style>
</head>
<body lang="en">
<div class="section-level-extent" id="Embedding-ECL">
<div class="nav-panel">
<p>
Previous: <a href="The-break-loop.html" accesskey="p" rel="prev">The break loop</a>, Up: <a href="User_0027s-guide.html" accesskey="u" rel="up">User&rsquo;s guide</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h3 class="section" id="Embedding-ECL-1">1.4 Embedding ECL</h3>
<ul class="mini-toc">
<li><a href="Embedding-ECL.html#Minimal-Example" accesskey="1">Minimal Example</a></li>
<li><a href="Embedding-ECL.html#Embedding-ECL-_002d-Embedding-Reference" accesskey="2">Embedding Reference</a></li>
</ul>
<div class="subsection-level-extent" id="Minimal-Example">
<h4 class="subsection">1.4.1 Minimal Example</h4>
<p>An example project is included in the ECL source distribution in the
<code class="code">examples/embed/</code> directory.
</p>
<p>This example consists of a Common Lisp library (<code class="code">hello-lisp.lisp</code>) and a
system definition (<code class="code">hello-lisp.asd</code>, See <a class="xref" href="System-building.html#Compiling-with-ASDF">Compiling with ASDF</a>) that is
called from a C program (<code class="code">hello.c</code>). The example <code class="code">Makefile</code> shows how
to build a static library from the Lisp library and link it with the C program.
</p>
<hr>
</div>
<div class="subsection-level-extent" id="Embedding-ECL-_002d-Embedding-Reference">
<div class="nav-panel">
<p>
Up: <a href="Embedding-ECL.html#Embedding-ECL" accesskey="u" rel="up">Embedding ECL</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsection" id="Embedding-Reference">1.4.2 Embedding Reference</h4>
<ul class="mini-toc">
<li><a href="Embedding-ECL.html#Starting-and-Stopping" accesskey="1">Starting and Stopping</a></li>
<li><a href="Embedding-ECL.html#Catching-Errors-and-Managing-Interrupts" accesskey="2">Catching Errors and Managing Interrupts</a></li>
</ul>
<hr>
<div class="subsubsection-level-extent" id="Starting-and-Stopping">
<div class="nav-panel">
<p>
Next: <a href="Embedding-ECL.html#Catching-Errors-and-Managing-Interrupts" accesskey="n" rel="next">Catching Errors and Managing Interrupts</a>, Up: <a href="Embedding-ECL.html#Embedding-ECL-_002d-Embedding-Reference" accesskey="u" rel="up">Embedding Reference</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsubsection" id="Starting-and-Stopping-1">1.4.2.1 Starting and Stopping</h4>
<a class="anchor" id="cl_005fboot"></a><a class="index-entry-id" id="index-cl_005fboot"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-cl_005fboot-1"><span class="category-def">Function: </span><span><code class="def-type">int</code> <strong class="def-name">cl_boot</strong> <code class="def-code-arguments">(int argc, char **argv);</code><a class="copiable-link" href='Embedding-ECL.html#index-cl_005fboot-1'> &para;</a></span></dt>
<dd><p>Setup the lisp environment.
</p><dl class="table">
<dt><var class="var">argc</var></dt>
<dd><p>An integer with the number of arguments to this program.
</p></dd>
<dt><var class="var">argv</var></dt>
<dd><p>A vector of strings with the arguments to this program.
</p></dd>
</dl>
<p><b class="b">Description</b>
</p>
<p>This function must be called before any other function from the ECL library, including the creation of any lisp object or evaluating any lisp code. The only exception are <code class="code"><a class="ref" href="Embedding-ECL.html#ecl_005fset_005foption">ecl_set_option</a></code> and <code class="code"><a class="ref" href="Embedding-ECL.html#ecl_005fget_005foption">ecl_get_option</a></code>.
</p>
</dd></dl>
<a class="anchor" id="cl_005fshutdown"></a><a class="index-entry-id" id="index-cl_005fshutdown"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-cl_005fshutdown-1"><span class="category-def">Function: </span><span><code class="def-type">int</code> <strong class="def-name">cl_shutdown</strong> <code class="def-code-arguments">(void);</code><a class="copiable-link" href='Embedding-ECL.html#index-cl_005fshutdown-1'> &para;</a></span></dt>
<dd><p>Close the lisp environment.
</p>
<p><b class="b">Description</b>
</p>
<p>This function must be called before exiting a program that uses the ECL environment. It performs some cleaning, including the execution of any finalizers, unloading shared libraries and deleting temporary files that were created by the compiler.
</p></dd></dl>
<a class="anchor" id="ecl_005fset_005foption"></a><a class="index-entry-id" id="index-ecl_005fset_005foption"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fset_005foption-1"><span class="category-def">Function: </span><span><code class="def-type">void</code> <strong class="def-name">ecl_set_option</strong> <code class="def-code-arguments">(int option, cl_fixnum value);</code><a class="copiable-link" href='Embedding-ECL.html#index-ecl_005fset_005foption-1'> &para;</a></span></dt>
<dd><p>Set a boot option.
</p>
<dl class="table">
<dt><var class="var">option</var></dt>
<dd><p>An integer from <a class="ref" href="Embedding-ECL.html#tab_003aboot_002doptions">Table 1.1</a>.
</p></dd>
<dt><var class="var">value</var></dt>
<dd><p>A <code class="code">cl_index</code> value for this option
</p></dd>
</dl>
<p><b class="b">Description</b>
</p>
<p>This functions sets the value of different options that have to be customized <em class="emph">before</em> ECL boots. The table of options and default values [<a class="ref" href="Embedding-ECL.html#tab_003aboot_002doptions">Table 1.1</a>] shows that some of them are boolean, and some of them are unsigned integers.
</p>
<p>We distinguish three sets of values. The first set determines whether ECL handles certain exceptions, such as access to forbidden regions of memory, interrupts via , floating point exceptions, etc.
</p>
<p>The second set is related to the sizes of different stacks. Currently ECL uses four stacks: a bind stack for keeping assignments to special variables; a frame stack for implementing blocks, tagbodys and catch points; an interpreter stack for evaluating bytecodes, and finally the machine or C stack, of the computer we run in. We can set the expected size of these stacks, together with the size of a safety area which, if penetrated, will lead to the generation of a correctable error.
</p>
<div class="float" id="tab_003aboot_002doptions">
<table class="multitable">
<thead><tr><th width="30%">Name <code class="code">(ECL_OPT_*)</code></th><th width="15%">Type</th><th width="16%">Default</th><th width="39%">Description</th></tr></thead>
<tbody><tr><td width="30%"><code class="code">INCREMENTAL_GC</code></td><td width="15%">boolean</td><td width="16%">TRUE</td><td width="39%">Activate generational garbage collector.</td></tr>
<tr><td width="30%"><code class="code">TRAP_SIGSEGV</code></td><td width="15%">boolean</td><td width="16%">TRUE</td><td width="39%">Capture <code class="code">SIGSEGV</code> signals.</td></tr>
<tr><td width="30%"><code class="code">TRAP_SIGFPE</code></td><td width="15%">boolean</td><td width="16%">TRUE</td><td width="39%">Capture floating point exceptions.</td></tr>
<tr><td width="30%"><code class="code">TRAP_SIGINT</code></td><td width="15%">boolean</td><td width="16%">TRUE</td><td width="39%">Capture user interrupts.</td></tr>
<tr><td width="30%"><code class="code">TRAP_SIGILL</code></td><td width="15%">boolean</td><td width="16%">TRUE</td><td width="39%">Capture <code class="code">SIGILL</code> exception.</td></tr>
<tr><td width="30%"><code class="code">TRAP_INTERRUPT_SIGNAL</code></td><td width="15%">boolean</td><td width="16%">TRUE</td><td width="39%">Capture the signal that implements <code class="code"><a class="ref" href="Native-threads.html#mp_003ainterrupt_002dprocess">mp:interrupt-process</a></code>.</td></tr>
<tr><td width="30%"><code class="code">SIGNAL_HANDLING_THREAD</code></td><td width="15%">boolean</td><td width="16%">TRUE</td><td width="39%">Create a signal to capture and process asynchronous threads (See <a class="xref" href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Asynchronous-signals">Asynchronous signals</a>).</td></tr>
<tr><td width="30%"><code class="code">BOOTED</code></td><td width="15%">boolean</td><td width="16%">TRUE/FALSE</td><td width="39%">Has ECL booted (read only).</td></tr>
<tr><td width="30%"><code class="code">BIND_STACK_SIZE</code></td><td width="15%">cl_index</td><td width="16%">8192</td><td width="39%">Size of stack for binding special variables.</td></tr>
<tr><td width="30%"><code class="code">BIND_STACK_SAFETY_AREA</code></td><td width="15%">cl_index</td><td width="16%">128</td><td width="39%"></td></tr>
<tr><td width="30%"><code class="code">FRAME_STACK_SIZE</code></td><td width="15%">cl_index</td><td width="16%">2048</td><td width="39%">Size of stack for nonlocal jumps.</td></tr>
<tr><td width="30%"><code class="code">FRAME_STACK_SAFETY_AREA</code></td><td width="15%">cl_index</td><td width="16%">128</td><td width="39%"></td></tr>
<tr><td width="30%"><code class="code">LISP_STACK_SIZE</code></td><td width="15%">cl_index</td><td width="16%">32768</td><td width="39%">Size of interpreter stack.</td></tr>
<tr><td width="30%"><code class="code">LISP_STACK_SAFETY_AREA</code></td><td width="15%">cl_index</td><td width="16%">128</td><td width="39%"></td></tr>
<tr><td width="30%"><code class="code">C_STACK_SIZE</code></td><td width="15%">cl_index</td><td width="16%">0 or 1048576</td><td width="39%">Size of C stack in bytes. The effect and default value of this option depends on the operating system. On Unix, the default is 0 which means that ECL will use the stack size provided by the OS. If set to a non-default value, ECL will set the stack size to the given value unless the stack size provided by the OS is already large enough. On Windows, the stack size is set at build time and cannot be changed at runtime. Here, we use a default of 1 MiB. For other operating systems, it is up to the user to set this value to the available stack size so that ECL can reliably detect stack overflows.</td></tr>
<tr><td width="30%"><code class="code">C_STACK_SAFETY_AREA</code></td><td width="15%">cl_index</td><td width="16%">4192</td><td width="39%"></td></tr>
<tr><td width="30%"><code class="code">THREAD_INTERRUPT_SIGNAL</code></td><td width="15%">unsigned int</td><td width="16%">0</td><td width="39%">If nonzero, specify the unix signal which is used to communicate between different Lisp threads.</td></tr>
</tbody>
</table>
<div class="caption"><p><strong class="strong">Table 1.1: </strong>Boot options for embedded ECL</p></div></div></dd></dl>
<a class="anchor" id="ecl_005fget_005foption"></a><a class="index-entry-id" id="index-ecl_005fget_005foption"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fget_005foption-1"><span class="category-def">Function: </span><span><code class="def-type">cl_fixnum</code> <strong class="def-name">ecl_get_option</strong> <code class="def-code-arguments">(int option);</code><a class="copiable-link" href='Embedding-ECL.html#index-ecl_005fget_005foption-1'> &para;</a></span></dt>
<dd><p>Read the value of a boot option.
</p><dl class="table">
<dt><var class="var">option</var></dt>
<dd><p>An integer from <a class="ref" href="Embedding-ECL.html#tab_003aboot_002doptions">Table 1.1</a>.
</p></dd>
</dl>
<p><b class="b">Description</b>
</p>
<p>This functions reads the value of different options that have to be customized <em class="emph">before</em> ECL boots. The table of options and default values is <a class="ref" href="Embedding-ECL.html#tab_003aboot_002doptions">Table 1.1</a>.
</p></dd></dl>
<a class="anchor" id="ecl_005fimport_005fcurrent_005fthread"></a><a class="index-entry-id" id="index-ecl_005fimport_005fcurrent_005fthread"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005fimport_005fcurrent_005fthread-1"><span class="category-def">Function: </span><span><code class="def-type">bool</code> <strong class="def-name">ecl_import_current_thread</strong> <code class="def-code-arguments">(cl_object name, cl_object bindings);</code><a class="copiable-link" href='Embedding-ECL.html#index-ecl_005fimport_005fcurrent_005fthread-1'> &para;</a></span></dt>
<dd><p>Import an external thread in the Lisp environment.
</p><dl class="table">
<dt><var class="var">name</var></dt>
<dd><p>Thread name.
</p></dd>
<dt><var class="var">bindings</var></dt>
<dd><p>Unused (specifying initial bindings for external threads is not supported currently)
</p></dd>
<dt><var class="var">returns</var></dt>
<dd><p>True if the thread was successfully imported, false otherwise.
</p></dd>
</dl>
<p><b class="b">Description</b>
</p>
<p>External threads, i.e. threads which are not created in the Lisp world using the routines described in <a class="ref" href="Native-threads.html#Processes-_0028native-threads_0029">Processes (native threads)</a>, need to be imported with <code class="code"><a class="ref" href="Embedding-ECL.html#ecl_005fimport_005fcurrent_005fthread">ecl_import_current_thread</a></code> before Lisp code can be executed.
</p>
<p><b class="b">See also</b>
</p>
<p><code class="code"><a class="ref" href="Embedding-ECL.html#ecl_005frelease_005fcurrent_005fthread">ecl_release_current_thread</a></code>
</p></dd></dl>
<a class="anchor" id="ecl_005frelease_005fcurrent_005fthread"></a><a class="index-entry-id" id="index-ecl_005frelease_005fcurrent_005fthread"></a>
<dl class="first-deftypefn first-deftypefun-alias-first-deftypefn">
<dt class="deftypefn deftypefun-alias-deftypefn" id="index-ecl_005frelease_005fcurrent_005fthread-1"><span class="category-def">Function: </span><span><code class="def-type">void</code> <strong class="def-name">ecl_release_current_thread</strong> <code class="def-code-arguments">(void);</code><a class="copiable-link" href='Embedding-ECL.html#index-ecl_005frelease_005fcurrent_005fthread-1'> &para;</a></span></dt>
<dd><p>Release an external thread imported with <code class="code"><a class="ref" href="Embedding-ECL.html#ecl_005fimport_005fcurrent_005fthread">ecl_import_current_thread</a></code>. Must be called before thread exit to prevent memory leaks.
</p></dd></dl>
<dl class="first-defvr">
<dt class="defvr" id="index-ECLDIR"><span class="category-def">Environment variable: </span><span><strong class="def-name">ECLDIR</strong><a class="copiable-link" href='Embedding-ECL.html#index-ECLDIR'> &para;</a></span></dt>
<dd><p>Specify a non-standard installation directory.
</p>
<p><b class="b">Description</b>
</p>
<p>ECL includes various files for external modules (e.g. asdf, sockets), character encodings or documentation strings. The installation directory for these files is chosen during build time by the configure script. If the directory is moved to a different place, the <code class="code">ECLDIR</code> environment variable should be updated accordingly. Note that the contents of the variable are parsed as a Common Lisp pathname, thus it must end with a slash.
</p></dd></dl>
<hr>
</div>
<div class="subsubsection-level-extent" id="Catching-Errors-and-Managing-Interrupts">
<div class="nav-panel">
<p>
Previous: <a href="Embedding-ECL.html#Starting-and-Stopping" accesskey="p" rel="prev">Starting and Stopping</a>, Up: <a href="Embedding-ECL.html#Embedding-ECL-_002d-Embedding-Reference" accesskey="u" rel="up">Embedding Reference</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
<h4 class="subsubsection" id="Catching-Errors-and-Managing-Interrupts-1">1.4.2.2 Catching Errors and Managing Interrupts</h4>
<a class="anchor" id="ECL_005fCATCH_005fALL"></a><a class="index-entry-id" id="index-ECL_005fCATCH_005fALL"></a>
<dl class="first-deffn first-defmac-alias-first-deffn">
<dt class="deffn defmac-alias-deffn" id="index-ECL_005fCATCH_005fALL-1"><span class="category-def">Macro: </span><span><strong class="def-name">ECL_CATCH_ALL</strong><a class="copiable-link" href='Embedding-ECL.html#index-ECL_005fCATCH_005fALL-1'> &para;</a></span></dt>
<dd><p>Create a protected region.
</p>
<p><b class="b">C Macro</b>
</p>
<div class="example">
<pre class="verbatim">cl_env_ptr env = ecl_process_env();
ECL_CATCH_ALL_BEGIN(env) {
/*
* Code that is protected. Uncaught lisp conditions, THROW,
* signals such as SIGSEGV and SIGBUS may cause jump to
* this region.
*/
} ECL_CATCH_ALL_IF_CAUGHT {
/*
* If the exception, lisp condition or other control transfer
* is caught, this code is executed.
*/
} ECL_CATCH_ALL_END
/*
* In all cases we exit here.
*/
</pre></div>
<p><b class="b">Description</b>
</p>
<p>This is a set of three macros that create an <code class="code">unwind-protect</code> region that prevents any nonlocal transfer of control to outer loops. In the Lisp speak, the previous code is equivalent to
</p>
<div class="example lisp">
<pre class="lisp-preformatted">(block nil
(unwind-protect
(progn
;; Code that is protected
)
(return nil)))
</pre></div>
<p>As explained in <code class="code"><a class="ref" href="Embedding-ECL.html#ECL_005fUNWIND_005fPROTECT">ECL_UNWIND_PROTECT</a></code>, it is normally advisable to set up an unwind-protect frame to avoid the embedded lisp code to perform arbitrary transfers of control.
</p>
<p><b class="b">See also</b>
</p>
<p><code class="code"><a class="ref" href="Embedding-ECL.html#ECL_005fUNWIND_005fPROTECT">ECL_UNWIND_PROTECT</a></code>
</p></dd></dl>
<a class="anchor" id="ECL_005fUNWIND_005fPROTECT"></a><a class="index-entry-id" id="index-ECL_005fUNWIND_005fPROTECT"></a>
<dl class="first-deffn first-defmac-alias-first-deffn">
<dt class="deffn defmac-alias-deffn" id="index-ECL_005fUNWIND_005fPROTECT-1"><span class="category-def">Macro: </span><span><strong class="def-name">ECL_UNWIND_PROTECT</strong><a class="copiable-link" href='Embedding-ECL.html#index-ECL_005fUNWIND_005fPROTECT-1'> &para;</a></span></dt>
<dd><p>Create a protected region.
</p>
<p><b class="b">C Macro</b>
</p>
<div class="example">
<pre class="verbatim">cl_env_ptr env = ecl_process_env();
ECL_UNWIND_PROTECT_BEGIN(env) {
/*
* Code that is protected. Uncaught lisp conditions, THROW,
* signals such as SIGSEGV and SIGBUS may cause jump to
* this region.
*/
} ECL_UNWIND_PROTECT_EXIT {
/*
* If the exception, lisp condition or other control transfer
* is caught, this code is executed. After this code, the
* process will jump to the original destination of the
* THROW, GOTO or other control statement that was interrupted.
*/
} ECL_UNWIND_PROTECT_END
/*
* We only exit here if NO nonlocal jump was interrupted.
*/
</pre></div>
<p><b class="b">Description</b>
</p>
<p>When embedding ECL it is normally advisable to set up an <code class="code">unwind-protect</code> frame to avoid the embedded lisp code to perform arbitrary transfers of control. Furthermore, the unwind protect form will be used in at least in the following occasions:
</p>
<ul class="itemize mark-bullet">
<li>In a normal program exit, caused by <code class="code"><a class="ref" href="Operating-System-Interface.html#ext_003aquit">ext:quit</a></code>, ECL unwinds up to the outermost frame, which may be an <code class="code"><a class="ref" href="Embedding-ECL.html#ECL_005fCATCH_005fALL">ECL_CATCH_ALL</a></code> or <code class="code"><a class="ref" href="Embedding-ECL.html#ECL_005fUNWIND_005fPROTECT">ECL_UNWIND_PROTECT</a></code> macro.
</li></ul>
<p>Besides this, normal mechanisms for exit, such as <code class="code"><a class="ref" href="Operating-System-Interface.html#ext_003aquit">ext:quit</a></code>, and uncaught exceptions, such as serious signals (See <a class="xref" href="Signals-and-Interrupts.html#Signals-and-Interrupts-_002d-Synchronous-signals">Synchronous signals</a>), are best handled using <code class="code">unwind-protect</code> blocks.
</p>
<p><b class="b">See also</b>
</p>
<p><code class="code"><a class="ref" href="Embedding-ECL.html#ECL_005fCATCH_005fALL">ECL_CATCH_ALL</a></code>
</p></dd></dl>
<a class="anchor" id="ecl_005fclear_005finterrupts"></a><a class="index-entry-id" id="index-ecl_005fclear_005finterrupts"></a>
<dl class="first-deffn first-defmac-alias-first-deffn">
<dt class="deffn defmac-alias-deffn" id="index-ecl_005fclear_005finterrupts-1"><span class="category-def">Macro: </span><span><strong class="def-name">ecl_clear_interrupts</strong> <var class="def-var-arguments">()</var><a class="copiable-link" href='Embedding-ECL.html#index-ecl_005fclear_005finterrupts-1'> &para;</a></span></dt>
<dd><p>Clear all pending signals and exceptions.
</p>
<p><b class="b">Description</b>
</p>
<p>This macro clears all pending interrupts.
</p>
<p><b class="b">See also</b>
</p>
<p><code class="code"><a class="ref" href="Embedding-ECL.html#ecl_005fdisable_005finterrupts">ecl_disable_interrupts</a></code> and <code class="code"><a class="ref" href="Embedding-ECL.html#ecl_005fenable_005finterrupts">ecl_enable_interrupts</a></code>.
</p></dd></dl>
<a class="anchor" id="ecl_005fdisable_005finterrupts"></a><a class="index-entry-id" id="index-ecl_005fdisable_005finterrupts"></a>
<dl class="first-deffn first-defmac-alias-first-deffn">
<dt class="deffn defmac-alias-deffn" id="index-ecl_005fdisable_005finterrupts-1"><span class="category-def">Macro: </span><span><strong class="def-name">ecl_disable_interrupts</strong> <var class="def-var-arguments">()</var><a class="copiable-link" href='Embedding-ECL.html#index-ecl_005fdisable_005finterrupts-1'> &para;</a></span></dt>
<dd><p>Postpone handling of signals and exceptions.
</p>
<p><b class="b">Description</b>
</p>
<p>This macro sets a thread-local flag indicating that all received signals should be queued for later processing. Note that it is not possible to execute lisp code while interrupts are disabled in this way. For this purpose, use the <code class="code"><a class="ref" href="Native-threads.html#mp_003awithout_002dinterrupts">mp:without-interrupts</a></code> macro. Every call to <code class="code"><a class="ref" href="Embedding-ECL.html#ecl_005fdisable_005finterrupts">ecl_disable_interrupts</a></code> must be followed by a corresponding call to <code class="code"><a class="ref" href="Embedding-ECL.html#ecl_005fenable_005finterrupts">ecl_enable_interrupts</a></code>, otherwise race conditions will appear.
</p>
<p><b class="b">See also</b>
</p>
<p><code class="code"><a class="ref" href="Embedding-ECL.html#ecl_005fenable_005finterrupts">ecl_enable_interrupts</a></code> and <code class="code"><a class="ref" href="Embedding-ECL.html#ecl_005fclear_005finterrupts">ecl_clear_interrupts</a></code>.
</p></dd></dl>
<a class="anchor" id="ecl_005fenable_005finterrupts"></a><a class="index-entry-id" id="index-ecl_005fenable_005finterrupts"></a>
<dl class="first-deffn first-defmac-alias-first-deffn">
<dt class="deffn defmac-alias-deffn" id="index-ecl_005fenable_005finterrupts-1"><span class="category-def">Macro: </span><span><strong class="def-name">ecl_enable_interrupts</strong> <var class="def-var-arguments">();</var><a class="copiable-link" href='Embedding-ECL.html#index-ecl_005fenable_005finterrupts-1'> &para;</a></span></dt>
<dd><p>Activate handling of signals and exceptions.
</p>
<p><b class="b">Description</b>
</p>
<p>This macro sets a thread-local flag indicating that all received signals can be handled. If there are any pending signals, they will be immediately processed.
</p>
<p><b class="b">See also</b>
</p>
<p><code class="code"><a class="ref" href="Embedding-ECL.html#ecl_005fdisable_005finterrupts">ecl_disable_interrupts</a></code> and <code class="code"><a class="ref" href="Embedding-ECL.html#ecl_005fclear_005finterrupts">ecl_clear_interrupts</a></code>.
</p></dd></dl>
<a class="anchor" id="ECL_005fWITH_005fLISP_005fFPE"></a><a class="index-entry-id" id="index-ECL_005fWITH_005fLISP_005fFPE"></a>
<dl class="first-deffn first-defmac-alias-first-deffn">
<dt class="deffn defmac-alias-deffn" id="index-ECL_005fWITH_005fLISP_005fFPE-1"><span class="category-def">Macro: </span><span><strong class="def-name">ECL_WITH_LISP_FPE</strong><a class="copiable-link" href='Embedding-ECL.html#index-ECL_005fWITH_005fLISP_005fFPE-1'> &para;</a></span></dt>
<dd><p>Execute Lisp code with correct floating point environment
</p>
<p><b class="b">Description</b>
</p>
<p>Unless floating point exceptions are disabled (via the
<code class="code">--without-fpe</code> configure option or <code class="code">ECL_OPT_TRAP_SIGFPE</code>
runtime option), ECL will change the floating point environment when
booting. This macro allows for execution of Lisp code while saving and
later restoring the floating point environment of surrounding C code
so that changes in the floating point environment don&rsquo;t leak outside.
</p>
<p><code class="code"><a class="ref" href="Embedding-ECL.html#ECL_005fWITH_005fLISP_005fFPE">ECL_WITH_LISP_FPE</a></code> can be also used before ECL has booted.
</p>
<a class="index-entry-id" id="index-Safely-executing-Lisp-code-with-floating-point-exceptions-in-embedding-program"></a>
<p><b class="b">Example</b>
</p>
<div class="example">
<pre class="verbatim">#include &lt;ecl/ecl.h&gt;
#include &lt;stdio.h&gt;
int main(int argc, char **argv) {
ECL_WITH_LISP_FPE_BEGIN {
cl_boot(argc, argv);
} ECL_WITH_LISP_FPE_END;
double a = 1.0 / 0.0;
double b;
ECL_WITH_LISP_FPE_BEGIN {
cl_object form = ecl_read_from_cstring(&quot;(handler-case&quot;
&quot;(/ 1d0 0d0)&quot;
&quot;(division-by-zero () 0d0))&quot;);
b = ecl_to_double(si_safe_eval(3, form, ECL_NIL, ECL_NIL));
} ECL_WITH_LISP_FPE_END;
printf(&quot;%g %g\n&quot;, a, b);
cl_shutdown();
return 0;
}
</pre></div>
<p>will output
</p><pre class="verbatim">inf 0
</pre>
<p><b class="b">See also</b>
</p>
<p><code class="code"><a class="ref" href="Numbers.html#ext_003atrap_002dfpe">ext:trap-fpe</a></code>
</p>
</dd></dl>
</div>
</div>
</div>
<hr>
<div class="nav-panel">
<p>
Previous: <a href="The-break-loop.html" accesskey="p" rel="prev">The break loop</a>, Up: <a href="User_0027s-guide.html" accesskey="u" rel="up">User&rsquo;s guide</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="Indexes.html" title="Index" rel="index">Index</a>]</p>
</div>
</body>
</html>