swig/Doc/internals.html
Thien-Thi Nguyen 36627e941a Acknowledge others' input.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@503 626c5289-ae23-0410-ae9c-e8d60b6d4f22
2000-06-28 02:30:27 +00:00

438 lines
13 KiB
HTML

<html>
<head>
<title>SWIG Internals</title>
</head>
<body>
<center>
<h1>SWIG Internals Manual</h1>
<b>Thien-Thi Nguyen <br>
ttn@glug.org <br>
(with much help from others) <br>
</b>
</center>
<p>
<b>$Header$</b>
<p>
(Note : This is a work in progress.)
<h2>1. Introduction</h2>
This document details SWIG internals: architecture and sometimes
implementation. The first few sections concentrate on data structures,
interfaces, conventions and code shared by all language targets.
Subsequent sections focus on a particular language.
<p>
The audience is assumed to be SWIG developers (who should also read the
<a href="engineering.html">SWIG Engineering Manual</a> before starting
to code).
<h3>Directory Guide</h3>
<table border=1>
<tr><td><a href="index.html">Doc</a></td>
<td>HTML documentation. If you find a documentation bug, please
<a href="mailto:bug-swig-doc@glug.org">let us know</a>.</td>
</tr>
<tr><td>Examples</td>
<td>This subdir tree contains examples of using SWIG w/ different
scripting languages, including makefiles. Typically, there are the
"simple" and "matrix" examples, w/ some languages offering additional
examples. The GIFPlot example has its own set of per-language
subdirectories. See the README more index.html file in each directory
for more info. [FIXME: Ref SWIG user manual.]</td>
</tr>
<tr><td>Lib</td>
<td>These are the <tt>.i</tt> (interface) files that form the SWIG
installed library. Language-specific files are in subdirectories (for
example, guile/typemaps.i). Each language also has a <tt>.swg</tt> file
implementing runtime type support for that language. The SWIG library
is not versioned.</td>
</tr>
<tr><td>Misc</td>
<td>Currently this subdir only contains file <tt>fileheader</tt>. See
the <a href="engineering.html">Engineering Manual</a> for more
info.</td>
</tr>
<tr><td>Runtime</td>
<td>This subdir contains scripts and a makefile for creating runtime
shared-object libraries used by various languages. Runtime/make.sh
says: "The runtime libraries are only needed if you are building
multiple extension modules that need to share information."</td>
</tr>
<tr><td>Source</td>
<td>SWIG source code is in this subdir tree. Directories marked w/ "(*)"
are used in building the <tt>swig</tt> executable.
<table border=1>
<tr><td>DOH (*)</td>
<td>C library providing memory allocation, file access and generic
containers. Result: libdoh.a</td>
</tr>
<tr><td>Expat</td>
<td>[TODO]</td>
</tr>
<tr><td>Experiment</td>
<td>[TODO]</td>
</tr>
<tr><td>Include (*)</td>
<td>Configuration .h files</td>
</tr>
<tr><td>LParse</td>
<td>Parser (lex / yacc) files and support [why not (*)?!]</td>
</tr>
<tr><td>Modules</td>
<td>[TODO]</td>
</tr>
<tr><td>Modules1.1 (*)</td>
<td>Language-specific callbacks that does actual code generation (each
language has a .cxx and a .h file). Result: libmodules11.a</td>
</tr>
<tr><td>Preprocessor (*)</td>
<td>SWIG-specialized C/C++ preprocessor. Result: libcpp.a</td>
</tr>
<tr><td>SWIG1.1 (*)</td>
<td>Parts of SWIG that are not language-specific, including option
processing and the type-mapping system. Result: libswig11.a</td>
</tr>
<tr><td>SWIG1.3</td>
<td>[TODO] [funny, nothing here is presently used for swig-1.3]</td>
</tr>
<tr><td>SWILL</td>
<td>[TODO]</td>
</tr>
<tr><td>Swig (*)</td>
<td>[TODO]</td>
</tr>
<tr><td>Swim</td>
<td>[TODO]</td>
</tr>
<tr><td>Swithe</td>
<td>[TODO]</td>
</tr>
<tr><td>Xmlparse</td>
<td>[TODO]</td>
</tr>
</table></td>
</tr>
<tr><td>Tools</td>
<td>Libtool support and the mkdist.py script.</td>
</tr>
<tr><td>Win</td>
<td>This improperly-named (spit spit) subdir only has README.txt.</td>
</tr>
</table>
<h3>Overall Program Flow</h3>
Here is the general control flow and where under subdir <tt>Source</tt>
to look for code:
<ul>
<li> <tt>Modules1.1/swigmain.cxx:main()</tt> is the program entry
point. It parses the language-specifying command-line option (for
example, <tt>-java</tt>), creating a new language-specific wrapping
object (each language is a C++ class derived from base class
<tt>Language</tt>). This object and the command-line is passed to
<tt>SWIG_main()</tt>, whose return value is the program exit value.
<li> <tt>SWIG1.1/main.cxx:SWIG_main()</tt> is the "real" main. It
initializes the preprocessor and typemap machinery, defines some
preprocessor symbols, locates the SWIG library, processes common
command-line options, and then calls the language-specific command-line
parser. From here there are three paths: "help", "checkout" and
everything else.
<ul>
<li> In "help" mode, clean up open files and exit.
<li> In "checkout" mode, copy specified files from the SWIG library
to the current directory. Errors cause error messages but no
non-lcoal exits.
<li> Otherwise, do wrapping: determine output file name(s), define
some preprocessor symbols and run the preprocessor, initialize
the interface-definition parser, set up the typemap for handling
new return strings, and finally do the language-specific parse
(by calling the language object's <tt>parse()</tt> method), which
creates output files by side-effect.
</ul>
Afterwards, remove temporary files, and clean up. If the command-line
included <tt>-freeze</tt>, go into an infinite loop; otherwise return the
error count.
<li> The language-specific <tt>parse()</tt> (and all other
language-specific code) lives in <tt>Modules1.1/foo.{h,cxx}</tt> for
language Foo. Typically, <tt>FOO::parse()</tt> calls
<tt>FOO::headers()</tt> and then the global function <tt>yyparse()</tt>,
which uses the callbacks registered by <tt>SWIG_main()</tt> above.
</ul>
<h3>Table of Contents</h3>
<ul>
<li><a name="i2" href="#2">2. DOH</a>
<li><a name="i3" href="#3">3. Types and Typemaps</a>
<li><a name="i4" href="#4">4. Parsing</a>
<li><a name="i5" href="#5">5. Difference Between SWIG 1.1 and SWIG 1.3</a>
<li><a name="i6" href="#6">6. Plans for SWIG 2.0</a>
<li><a name="i7" href="#7">7. Reserved</a>
<li><a name="i8" href="#8">8. Reserved</a>
<li><a name="i9" href="#9">9. Reserved</a>
<li><a name="i10" href="#10">10. Guile Support</a>
<li><a name="i11" href="#11">11. Python Support</a>
<li><a name="i12" href="#12">12. Perl Support</a>
<li><a name="i13" href="#13">13. Java Support</a>
</ul>
<a name="2" href="#i2">
<h2>2. DOH</h2>
</a>
[TODO]
<a name="3" href="#i3">
<h2>3. Types and Typemaps</h2>
</a>
[TODO]
<a name="4" href="#i4">
<h2>4. Parsing</h2>
</a>
[TODO]
<a name="5" href="#i5">
<h2>5. Difference Between SWIG 1.1 and SWIG 1.3</h2>
</a>
[TODO]
<a name="6" href="#i6">
<h2>6. Plans for SWIG 2.0</h2>
</a>
[TODO]
<a name="7" href="#i7">
<h2>7. Reserved</h2>
</a>
<a name="8" href="#i8">
<h2>8. Reserved</h2>
</a>
<a name="9" href="#i9">
<h2>9. Reserved</h2>
</a>
<a name="10" href="#i10">
<h2>10. Guile Support</h2>
</a>
This section details guile-specific support in SWIG.
<h3>Meaning of "Module"</h3>
<p>
There are three different concepts of "module" involved, defined
separately for SWIG, Guile, and Libtool. To avoid horrible confusion,
we explicitly prefix the context, e.g., "guile-module".
<h3>Linkage</h3>
<p>
Guile support is complicated by a lack of user community cohesiveness,
which manifests in multiple shared-library usage conventions. A set of
policies implementing a usage convention is called a <b>linkage</b>.
The default linkage is the simplest; nothing special is done. In this
case <code>SWIG_init()</code> is provided and users must do something
like this:
<blockquote>
<pre>
(define my-so (dynamic-link "./example.so"))
(dynamic-call "SWIG_init" my-so)
</pre>
</blockquote>
At this time, the name <code>SWIG_init</code> is hardcoded; this
approach does not work with multiple swig-modules. NOTE: The "simple"
and "matrix" examples under Examples/guile include guilemain.i; the
resulting standalone interpreter does not require calls to
<code>dynamic-link</code> and <code>dynamic-call</code>, as shown here.
<p>
A second linkage creates "libtool dl module" wrappers, and currently is
broken. Whoever fixes this needs to track Guile's libtool dl module
convention, since that is not finalized.
<p>
The only other linkage supported at this time creates shared object
libraries suitable for use by hobbit's <code>(hobbit4d link)</code>
guile module. This is called the "hobbit" linkage, and requires also
using the "-package" command line option to set the part of the module
name before the last symbol. For example, both command lines:
[checkme:ttn]
<blockquote>
<pre>
swig -guile -package my/lib foo.i
swig -guile -package my/lib -module foo foo.i
</pre>
</blockquote>
would create module <code>(my lib foo)</code> (assuming in the first
case foo.i declares the module to be "foo"). The installed files are
my/lib/libfoo.so.X.Y.Z and friends. This scheme is still very
experimental; the (hobbit4d link) conventions are not well understood.
<p>
There are no other linkage types planned, but that could change... To
add a new type, add the name to the enum in guile.h and add the case to
<code>GUILE::emit_linkage()</code>.
<h3>Underscore Folding</h3>
<p>
Underscores are converted to dashes in identifiers. Guile support may
grow an option to inhibit this folding in the future, but no one has
complained so far.
<h3>Typemaps</h3>
<p>
It used to be that the mappings for "native" types were included in
guile.cxx. This information is now in Lib/guile/typemaps.i, which
presents a new challenge: how to have SWIG include typemaps.i before
processing the user's foo.i. At this time, we must say:
<blockquote>
<pre>
%include guile/typemaps.i
</pre>
</blockquote>
in foo.i. This may change in the future.
<h3>Smobs</h3>
<p>
For pointer types, SWIG can use Guile smobs if given the command-line
option "-with-smobs". Ultimately this will be the default (and only)
behavior and the command-line option will no longer be supported.
Ideally, "-with-smobs" will not even make it to beta.
<p>
Currently, one wrapper module must be generated without
<code>-c</code> and compiled with <code>-DSWIG_GLOBAL</code>, all the
other wrapper modules must be generated with <code>-c</code>. Maybe
one should move all the global helper functions that come from
<code>guile.swg</code> into a library, which is built by <code>make
runtime</code>.
<p>
In earlier versions of SWIG, C pointers were represented as Scheme
strings containing a hexadecimal rendering of the pointer value and a
mangled type name. As Guile allows registering user types, so-called
"smobs" (small objects), a much cleaner representation has been
implemented now. The details will be discussed in the following.
<p>
A smob is a cons cell where the lower half of the CAR contains the
smob type tag, while the upper half of the CAR and the whole CDR are
available. <code>SWIG_Guile_Init()</code> registers a smob type named
"swig" with Guile; its type tag is stored in the variable
<code>swig_tag</code>. The upper half of the CAR store an index into
a table of all C pointer types seen so far, to which new types seen
are appended. The CDR stores the pointer value. SWIG smobs print
like this: <code>#&lt;swig struct xyzzy * 0x1234affe&gt;</code> Two of
them are <code>equal?</code> if and only if they have the same type
and value.
<p>
To construct a Scheme object from a C pointer, the wrapper code calls
the function <code>SWIG_Guile_MakePtr_Str()</code>, passing both a
mangled type string and a pretty type string. The former is looked up
in the type table to get the type index to store in the upper half of
the CAR. If the type is new, it is appended to type table.
<p>
To get the pointer represented by a smob, the wrapper code calls the
function <code>SWIG_Guile_GetPtr_Str</code>, passing the mangled name
of the expected pointer type, which is used for looking up the type in
the type table and accessing the list of compatible types. If the
Scheme object passed was not a SWIG smob representing a compatible
pointer, a <code>wrong-type-arg</code> exception is raised.
<h3>Exception Handling</h3>
<p>
SWIG code calls <code>scm_error</code> on exception, using the following
mapping:
<pre>
MAP(SWIG_MemoryError, "swig-memory-error");
MAP(SWIG_IOError, "swig-io-error");
MAP(SWIG_RuntimeError, "swig-runtime-error");
MAP(SWIG_IndexError, "swig-index-error");
MAP(SWIG_TypeError, "swig-type-error");
MAP(SWIG_DivisionByZero, "swig-division-by-zero");
MAP(SWIG_OverflowError, "swig-overflow-error");
MAP(SWIG_SyntaxError, "swig-syntax-error");
MAP(SWIG_ValueError, "swig-value-error");
MAP(SWIG_SystemError, "swig-system-error");
</pre>
<p>
The default when not specified here is to use "swig-error".
See Lib/exception.i for details.
<a name="11" href="#i11">
<h2>10. Python Support</h2>
</a>
[TODO]
<a name="12" href="#i12">
<h2>10. Perl Support</h2>
</a>
[TODO]
<a name="13" href="#i13">
<h2>10. Java Support</h2>
</a>
[TODO]
</body>
</html>