mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-13 06:50:39 -08:00
587 lines
No EOL
50 KiB
HTML
587 lines
No EOL
50 KiB
HTML
|
|
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
|
|
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
|
|
<title>16. Protocol inheritance — Memory Pool System 1.111.0 documentation</title>
|
|
|
|
<link rel="stylesheet" href="../_static/mps.css" type="text/css" />
|
|
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
|
|
|
<script type="text/javascript">
|
|
var DOCUMENTATION_OPTIONS = {
|
|
URL_ROOT: '../',
|
|
VERSION: '1.111.0',
|
|
COLLAPSE_INDEX: false,
|
|
FILE_SUFFIX: '.html',
|
|
HAS_SOURCE: true
|
|
};
|
|
</script>
|
|
<script type="text/javascript" src="../_static/jquery.js"></script>
|
|
<script type="text/javascript" src="../_static/underscore.js"></script>
|
|
<script type="text/javascript" src="../_static/doctools.js"></script>
|
|
<link rel="copyright" title="Copyright" href="../copyright.html" />
|
|
<link rel="top" title="Memory Pool System 1.111.0 documentation" href="../index.html" />
|
|
<link rel="up" title="Design" href="index.html" />
|
|
<link rel="next" title="17. General MPS types" href="type.html" />
|
|
<link rel="prev" title="15. Debugging features for client objects" href="object-debug.html" />
|
|
</head>
|
|
<body>
|
|
<div class="related">
|
|
<h3>Navigation</h3>
|
|
<ul>
|
|
<li class="right" style="margin-right: 10px">
|
|
<a href="../genindex.html" title="General Index"
|
|
accesskey="I">index</a></li>
|
|
<li class="right" >
|
|
<a href="type.html" title="17. General MPS types"
|
|
accesskey="N">next</a> |</li>
|
|
<li class="right" >
|
|
<a href="object-debug.html" title="15. Debugging features for client objects"
|
|
accesskey="P">previous</a> |</li>
|
|
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> »</li>
|
|
<li><a href="index.html" accesskey="U">Design</a> »</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="document">
|
|
<div class="documentwrapper">
|
|
<div class="bodywrapper">
|
|
<div class="body">
|
|
|
|
<div class="section" id="protocol-inheritance">
|
|
<span id="design.mps.protocol"></span><h1>16. Protocol inheritance<a class="headerlink" href="#protocol-inheritance" title="Permalink to this headline">¶</a></h1>
|
|
<div class="section" id="introduction">
|
|
<h2>16.1. Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2>
|
|
<p><span class="target" id="design.mps.protocol.intro"></span><a class="mpstag reference internal" href="#design.mps.protocol.intro">.intro:</a> This document explains the design of the support for
|
|
class inheritance in MPS. It is not yet complete. It describes support
|
|
for single inheritance of classes. Future extensions will describe
|
|
multiple inheritance and the relationship between instances and
|
|
classes.</p>
|
|
<p><span class="target" id="design.mps.protocol.readership"></span><a class="mpstag reference internal" href="#design.mps.protocol.readership">.readership:</a> This document is intended for any MPS developer.</p>
|
|
</div>
|
|
<div class="section" id="history">
|
|
<h2>16.2. History<a class="headerlink" href="#history" title="Permalink to this headline">¶</a></h2>
|
|
<p><span class="target" id="design.mps.protocol.hist.0"></span><a class="mpstag reference internal" href="#design.mps.protocol.hist.0">.hist.0:</a> Written by Tony 1998-10-12</p>
|
|
</div>
|
|
<div class="section" id="purpose">
|
|
<h2>16.3. Purpose<a class="headerlink" href="#purpose" title="Permalink to this headline">¶</a></h2>
|
|
<p><span class="target" id="design.mps.protocol.purpose.code-maintain"></span><a class="mpstag reference internal" href="#design.mps.protocol.purpose.code-maintain">.purpose.code-maintain:</a> The purpose of the protocol
|
|
inheritance design is to ensure that the MPS code base can make use of
|
|
the benefits of object-oriented class inheritance to maximize code
|
|
reuse, minimize code maintenance and minimize the use of boilerplate
|
|
code.</p>
|
|
<p><span class="target" id="design.mps.protocol.purpose.related"></span><a class="mpstag reference internal" href="#design.mps.protocol.purpose.related">.purpose.related:</a> For related discussion, see
|
|
mail.tony.1998-08-28.16-26(0), mail.tony.1998-09-01.11-38(0),
|
|
mail.tony.1998-10-06.11-03(0) and other messages in the same threads.</p>
|
|
</div>
|
|
<div class="section" id="requirements">
|
|
<h2>16.4. Requirements<a class="headerlink" href="#requirements" title="Permalink to this headline">¶</a></h2>
|
|
<p><span class="target" id="design.mps.protocol.req.implicit"></span><a class="mpstag reference internal" href="#design.mps.protocol.req.implicit">.req.implicit:</a> The object system should provide a means for
|
|
classes to inherit the methods of their direct superclasses implicitly
|
|
for all functions in the protocol without having to write any explicit
|
|
code for each inherited function.</p>
|
|
<p><span class="target" id="design.mps.protocol.req.override"></span><a class="mpstag reference internal" href="#design.mps.protocol.req.override">.req.override:</a> There must additionally be a way for classes
|
|
to override the methods of their superclasses.</p>
|
|
<p><span class="target" id="design.mps.protocol.req.next-method"></span><a class="mpstag reference internal" href="#design.mps.protocol.req.next-method">.req.next-method:</a> As a result of <a class="reference internal" href="#design.mps.protocol.req.implicit">.req.implicit</a>,
|
|
classes cannot make static assumptions about methods used by direct
|
|
superclasses. The object system must provide a means for classes to
|
|
extend (not just replace) the behaviour of protocol functions, such as
|
|
a mechanism for invoking the “next-method”.</p>
|
|
<p><span class="target" id="design.mps.protocol.req.ideal.extend"></span><a class="mpstag reference internal" href="#design.mps.protocol.req.ideal.extend">.req.ideal.extend:</a> The object system must provide a standard
|
|
way for classes to implement the protocol supported by they superclass
|
|
and additionally add new methods of their own which can be specialized
|
|
by subclasses.</p>
|
|
<p><span class="target" id="design.mps.protocol.req.ideal.multiple-inheritance"></span><a class="mpstag reference internal" href="#design.mps.protocol.req.ideal.multiple-inheritance">.req.ideal.multiple-inheritance:</a> The object system should
|
|
support multiple inheritance such that sub-protocols can be “mixed in”
|
|
with several classes which do not themselves support identical
|
|
protocols.</p>
|
|
</div>
|
|
<div class="section" id="overview">
|
|
<h2>16.5. Overview<a class="headerlink" href="#overview" title="Permalink to this headline">¶</a></h2>
|
|
<p><span class="target" id="design.mps.protocol.overview.root"></span><a class="mpstag reference internal" href="#design.mps.protocol.overview.root">.overview.root:</a> We start with the root of all conformant
|
|
class hierarchies, which is called <tt class="xref c c-type docutils literal"><span class="pre">ProtocolClass</span></tt>. This is an
|
|
“abstract” class (that is, it has no direct instances, but it is
|
|
intended to have subclasses). To use Dylan terminology, instances of
|
|
its subclasses are “general” instances of ProtocolClass. They look
|
|
like this:</p>
|
|
<div class="highlight-c"><div class="highlight"><pre><span class="n">Instance</span> <span class="n">Object</span> <span class="n">Class</span> <span class="n">Object</span>
|
|
|
|
<span class="o">--------------------</span> <span class="o">--------------------</span>
|
|
<span class="o">|</span> <span class="n">sig</span> <span class="o">|</span> <span class="o">|-------->|</span> <span class="n">sig</span> <span class="o">|</span>
|
|
<span class="o">--------------------</span> <span class="o">|</span> <span class="o">--------------------</span>
|
|
<span class="o">|</span> <span class="n">class</span> <span class="o">|----|</span> <span class="o">|</span> <span class="n">superclass</span> <span class="o">|</span>
|
|
<span class="o">--------------------</span> <span class="o">--------------------</span>
|
|
<span class="o">|</span> <span class="p">...</span> <span class="o">|</span> <span class="o">|</span> <span class="n">coerceInst</span> <span class="o">|</span>
|
|
<span class="o">--------------------</span> <span class="o">--------------------</span>
|
|
<span class="o">|</span> <span class="p">...</span> <span class="o">|</span> <span class="o">|</span> <span class="n">coerceClass</span> <span class="o">|</span>
|
|
<span class="o">--------------------</span> <span class="o">--------------------</span>
|
|
<span class="o">|</span> <span class="o">|</span> <span class="o">|</span> <span class="p">...</span> <span class="o">|</span>
|
|
</pre></div>
|
|
</div>
|
|
<p><span class="target" id="design.mps.protocol.overview.inherit"></span><a class="mpstag reference internal" href="#design.mps.protocol.overview.inherit">.overview.inherit:</a> Classes inherit the protocols supported by
|
|
their superclasses. By default they have the same methods as the
|
|
class(es) from which they inherit.</p>
|
|
<p><span class="target" id="design.mps.protocol.overview.inherit.specialize"></span><a class="mpstag reference internal" href="#design.mps.protocol.overview.inherit.specialize">.overview.inherit.specialize:</a> Classes may specialize the
|
|
behaviour of their superclass. They do this by by overriding methods
|
|
or other fields in the class object.</p>
|
|
<p><span class="target" id="design.mps.protocol.overview.extend"></span><a class="mpstag reference internal" href="#design.mps.protocol.overview.extend">.overview.extend:</a> Classes may extend the protocols supported
|
|
by their superclasses by adding new fields for methods or other data.</p>
|
|
<p><span class="target" id="design.mps.protocol.overview.sig.inherit"></span><a class="mpstag reference internal" href="#design.mps.protocol.overview.sig.inherit">.overview.sig.inherit:</a> Classes will contain (possibly
|
|
several) signatures. Classes must not specialize (override) the
|
|
signatures they inherit from their superclasses.</p>
|
|
<p><span class="target" id="design.mps.protocol.overview.sig.extend"></span><a class="mpstag reference internal" href="#design.mps.protocol.overview.sig.extend">.overview.sig.extend:</a> If a class definition extends a
|
|
protocol, it is normal policy for the class definition to include a
|
|
new signature as the last field in the class object.</p>
|
|
<p><span class="target" id="design.mps.protocol.overview.coerce-class"></span><a class="mpstag reference internal" href="#design.mps.protocol.overview.coerce-class">.overview.coerce-class:</a> Each class contains a <tt class="docutils literal"><span class="pre">coerceClass</span></tt>
|
|
field. This contains a method which can find the part of the class
|
|
object which implements the protocols of a supplied superclass
|
|
argument (if, indeed, the argument <em>is</em> a superclass). This function
|
|
may be used for testing subclass/superclass relationships, and it also
|
|
provides support for multiple inheritance.</p>
|
|
<p><span class="target" id="design.mps.protocol.overview.coerce-inst"></span><a class="mpstag reference internal" href="#design.mps.protocol.overview.coerce-inst">.overview.coerce-inst:</a> Each class contains a <tt class="docutils literal"><span class="pre">coerceInst</span></tt>
|
|
field. This contains a method which can find the part of an instance
|
|
object which contains the instance slots of a supplied superclass
|
|
argument (if, indeed, the argument <em>is</em> a superclass). This function
|
|
may be used for testing whether an object is an instance of a given
|
|
class, and it also provides support for multiple inheritance.</p>
|
|
<p><span class="target" id="design.mps.protocol.overview.superclass"></span><a class="mpstag reference internal" href="#design.mps.protocol.overview.superclass">.overview.superclass:</a> Each class contains a <tt class="docutils literal"><span class="pre">superclass</span></tt>
|
|
field. This enables classes to call “next-method”, as well as enabling
|
|
the coercion functions.</p>
|
|
<p><span class="target" id="design.mps.protocol.overview.next-method"></span><a class="mpstag reference internal" href="#design.mps.protocol.overview.next-method">.overview.next-method:</a> A specialized method in a class can
|
|
make use of an overridden method from a superclass by accessing the
|
|
method from the appropriate field in the superclass object and calling
|
|
it. The superclass may be accessed indirectly from the class’s
|
|
“Ensure” function when it is statically known (see
|
|
<a class="reference internal" href="#design.mps.protocol.overview.access">.overview.access</a>). This permits “next-method” calls, and
|
|
is fully scalable in that it allows arbitrary length method chains.
|
|
The <tt class="xref c c-func docutils literal"><span class="pre">SUPERCLASS()</span></tt> macro helps with this (see
|
|
<a class="reference internal" href="#design.mps.protocol.int.static-superclass">.int.static-superclass</a>).</p>
|
|
<p><span class="target" id="design.mps.protocol.overview.next-method.naive"></span><a class="mpstag reference internal" href="#design.mps.protocol.overview.next-method.naive">.overview.next-method.naive:</a> In some cases it is necessary to
|
|
write a method which is designed to specialize an inherited method,
|
|
needs to call the next-method, and yet the implementation doesn’t have
|
|
static knowledge of the superclass. This might happen because the
|
|
specialized method is designed to be reusable by many class
|
|
definitions. The specialized method can usually locate the class
|
|
object from one of the parameters passed to the method. It can then
|
|
access the superclass through the <tt class="docutils literal"><span class="pre">superclass</span></tt> field of the class,
|
|
and hence call the next method. This technique has some limitations
|
|
and doesn’t support longer method chains. It is also dependent on none
|
|
of the class definitions which use the method having any subclasses.</p>
|
|
<p><span class="target" id="design.mps.protocol.overview.access"></span><a class="mpstag reference internal" href="#design.mps.protocol.overview.access">.overview.access:</a> Classes must be initialized by calls to
|
|
functions, since it is these function calls which copy properties from
|
|
superclasses. Each class must provide an “Ensure” function, which
|
|
returns the canonical copy of the class. The canonical copy may reside
|
|
in static storage, but no MPS code may refer to that static storage by
|
|
name.</p>
|
|
<p><span class="target" id="design.mps.protocol.overview.naming"></span><a class="mpstag reference internal" href="#design.mps.protocol.overview.naming">.overview.naming:</a> There are some strict naming conventions
|
|
which must be followed when defining and using classes. The use is
|
|
obligatory because it is assumed by the macros which support the
|
|
definition and inheritance mechanism. For every class <tt class="docutils literal"><span class="pre">SomeClass</span></tt>,
|
|
we insist upon the following naming conventions:-</p>
|
|
<p><tt class="docutils literal"><span class="pre">SomeClassStruct</span></tt></p>
|
|
<blockquote>
|
|
<div>names the type of the structure for the protocol class. This might
|
|
be a <tt class="docutils literal"><span class="pre">typedef</span></tt> which aliases the type to the type of the
|
|
superclass, but if the class has extended the protocols of the
|
|
superclass the it will be a type which contains the new class
|
|
fields.</div></blockquote>
|
|
<p><tt class="docutils literal"><span class="pre">SomeClass</span></tt></p>
|
|
<blockquote>
|
|
<div>names the type <tt class="docutils literal"><span class="pre">*SomeClassStruct</span></tt>. This might be a <tt class="docutils literal"><span class="pre">typedef</span></tt>
|
|
which aliases the type to the type of the superclass, but if the
|
|
class has extended the protocols of the superclass then it will be
|
|
a type which contains the new class fields.</div></blockquote>
|
|
<p><tt class="docutils literal"><span class="pre">EnsureSomeClass()</span></tt></p>
|
|
<blockquote>
|
|
<div>names the function that returns the initialized class object.</div></blockquote>
|
|
</div>
|
|
<div class="section" id="interface">
|
|
<h2>16.6. Interface<a class="headerlink" href="#interface" title="Permalink to this headline">¶</a></h2>
|
|
<div class="section" id="class-definition">
|
|
<h3>16.6.1. Class definition<a class="headerlink" href="#class-definition" title="Permalink to this headline">¶</a></h3>
|
|
<p><span class="target" id="design.mps.protocol.int.define-class"></span><a class="mpstag reference internal" href="#design.mps.protocol.int.define-class">.int.define-class:</a> Class definition is performed by the macro
|
|
<tt class="docutils literal"><span class="pre">DEFINE_CLASS(className,</span> <span class="pre">var)</span></tt>. A call to the macro must be followed
|
|
by a body of initialization code in braces <tt class="docutils literal"><span class="pre">{}</span></tt>. The parameter
|
|
<tt class="docutils literal"><span class="pre">className</span></tt> is used to name the class being defined. The parameter
|
|
<tt class="docutils literal"><span class="pre">var</span></tt> is used to name a local variable of type <tt class="docutils literal"><span class="pre">className</span></tt>, which
|
|
is defined by the macro; it refers to the canonical storage for the
|
|
class being defined. This variable may be used in the initialization
|
|
code. (The macro doesn’t just pick a name implicitly because of the
|
|
danger of a name clash with other names used by the programmer). A
|
|
call to <tt class="docutils literal"><span class="pre">DEFINE_CLASS(SomeClass,</span> <span class="pre">var)</span></tt> defines the
|
|
<tt class="docutils literal"><span class="pre">EnsureSomeClass()</span></tt> function, defines some static storage for the
|
|
canonical class object, and defines some other things to ensure the
|
|
class gets initialized exactly once.</p>
|
|
<p><span class="target" id="design.mps.protocol.int.define-alias-class"></span><a class="mpstag reference internal" href="#design.mps.protocol.int.define-alias-class">.int.define-alias-class:</a> A convenience macro
|
|
<tt class="xref c c-func docutils literal"><span class="pre">DEFINE_ALIAS_CLASS()</span></tt> is provided which both performs the class
|
|
definition and defines the types <tt class="docutils literal"><span class="pre">SomeClass</span></tt> and <tt class="docutils literal"><span class="pre">SomeClass</span>
|
|
<span class="pre">struct</span></tt> as aliases for some other class types. This is particularly
|
|
useful for classes which simply inherit, and don’t extend protocols.
|
|
The macro call <tt class="docutils literal"><span class="pre">DEFINE_ALIAS_CLASS(className,</span> <span class="pre">superName,</span> <span class="pre">var)</span></tt> is
|
|
exactly equivalent to the following:</p>
|
|
<div class="highlight-c"><div class="highlight"><pre><span class="k">typedef</span> <span class="n">superName</span> <span class="n">className</span><span class="p">;</span>
|
|
<span class="k">typedef</span> <span class="n">superNameStruct</span> <span class="n">classNameStruct</span><span class="p">;</span>
|
|
<span class="n">DEFINE_CLASS</span><span class="p">(</span><span class="n">className</span><span class="p">,</span> <span class="n">var</span><span class="p">)</span>
|
|
</pre></div>
|
|
</div>
|
|
<p><span class="target" id="design.mps.protocol.int.define-special"></span><a class="mpstag reference internal" href="#design.mps.protocol.int.define-special">.int.define-special:</a> If classes are particularly likely to be
|
|
subclassed without extension, the class implementor may choose to
|
|
provide a convenience macro which expands into
|
|
<tt class="xref c c-func docutils literal"><span class="pre">DEFINE_ALIAS_CLASS()</span></tt> with an appropriate name for the
|
|
superclass. For example, there might be a macro for defining pool
|
|
classes such that the macro call <tt class="docutils literal"><span class="pre">DEFINE_POOL_CLASS(className,</span> <span class="pre">var)</span></tt>
|
|
is exactly equivalent to the macro call
|
|
<tt class="docutils literal"><span class="pre">DEFINE_ALIAS_CLASS(className,</span> <span class="pre">PoolClass,</span> <span class="pre">var)</span></tt>. It may also be
|
|
convenient to define a static superclass accessor macro at the same
|
|
time (see <a class="reference internal" href="#design.mps.protocol.int.static-superclass.special">.int.static-superclass.special</a>).</p>
|
|
</div>
|
|
<div class="section" id="single-inheritance">
|
|
<h3>16.6.2. Single inheritance<a class="headerlink" href="#single-inheritance" title="Permalink to this headline">¶</a></h3>
|
|
<p><span class="target" id="design.mps.protocol.int.inheritance"></span><a class="mpstag reference internal" href="#design.mps.protocol.int.inheritance">.int.inheritance:</a> Class inheritance details must be provided
|
|
in the class initialization code (see <a class="reference internal" href="#design.mps.protocol.int.define-class">.int.define-class</a>).
|
|
Inheritance is performed by the macro
|
|
<tt class="docutils literal"><span class="pre">INHERIT_CLASS(thisClassCoerced,</span> <span class="pre">parentClassName)</span></tt>. A call to this
|
|
macro will make the class being defined a direct subclass of
|
|
<tt class="docutils literal"><span class="pre">parentClassName</span></tt> by ensuring that all the fields of the parent
|
|
class are copied into <tt class="docutils literal"><span class="pre">thisClass</span></tt>, and setting the superclass field
|
|
of <tt class="docutils literal"><span class="pre">thisClass</span></tt> to be the parent class object. The parameter
|
|
<tt class="docutils literal"><span class="pre">thisClassCoerced</span></tt> must be of type <tt class="docutils literal"><span class="pre">parentClassName</span></tt>. If the class
|
|
definition defines an alias class (see
|
|
<a class="reference internal" href="#design.mps.protocol.int.define-alias-class">.int.define-alias-class</a>), then the variable named as the
|
|
second parameter to <tt class="xref c c-func docutils literal"><span class="pre">DEFINE_CLASS()</span></tt> will be appropriate to pass
|
|
to <tt class="xref c c-func docutils literal"><span class="pre">INHERIT_CLASS()</span></tt>.</p>
|
|
</div>
|
|
<div class="section" id="specialization">
|
|
<h3>16.6.3. Specialization<a class="headerlink" href="#specialization" title="Permalink to this headline">¶</a></h3>
|
|
<p><span class="target" id="design.mps.protocol.int.specialize"></span><a class="mpstag reference internal" href="#design.mps.protocol.int.specialize">.int.specialize:</a> Class specialization details must be given
|
|
explicitly in the class initialization code (see
|
|
<a class="reference internal" href="#design.mps.protocol.int.define-class">.int.define-class</a>). This must happen <em>after</em> the
|
|
inheritance details are given (see <a class="reference internal" href="#design.mps.protocol.int.inheritance">.int.inheritance</a>).</p>
|
|
</div>
|
|
<div class="section" id="extension">
|
|
<h3>16.6.4. Extension<a class="headerlink" href="#extension" title="Permalink to this headline">¶</a></h3>
|
|
<p><span class="target" id="design.mps.protocol.int.extend"></span><a class="mpstag reference internal" href="#design.mps.protocol.int.extend">.int.extend:</a> To extend the protocol when defining a new
|
|
class, a new type must be defined for the class structure. This must
|
|
embed the structure for the primarily inherited class as the first
|
|
field of the structure. Class extension details must be given
|
|
explicitly in the class initialization code (see
|
|
<a class="reference internal" href="#design.mps.protocol.int.define-class">.int.define-class</a>). This must happen <em>after</em> the
|
|
inheritance details are given (see <a class="reference internal" href="#design.mps.protocol.int.inheritance">.int.inheritance</a>).</p>
|
|
</div>
|
|
<div class="section" id="introspection">
|
|
<h3>16.6.5. Introspection<a class="headerlink" href="#introspection" title="Permalink to this headline">¶</a></h3>
|
|
<p><span class="target" id="design.mps.protocol.introspect.c-lang"></span><a class="mpstag reference internal" href="#design.mps.protocol.introspect.c-lang">.introspect.c-lang:</a> The design includes a number of
|
|
introspection functions for dynamically examining class relationships.
|
|
These functions are polymorphic and accept arbitrary subclasses of
|
|
<tt class="xref c c-type docutils literal"><span class="pre">ProtocolClass</span></tt>. C doesn’t support such polymorphism. So
|
|
although these have the semantics of functions (and could be
|
|
implemented as functions in another language with compatible calling
|
|
conventions) they are actually implemented as macros. The macros are
|
|
named as method-style macros despite the fact that this arguably
|
|
contravenes guide.impl.c.macro.method. The justification
|
|
for this is that this design is intended to promote the use of
|
|
polymorphism, and it breaks the abstraction for the users to need to
|
|
be aware of what can and can’t be expressed directly in C function
|
|
syntax. These functions all have names ending in <tt class="docutils literal"><span class="pre">Poly</span></tt> to identify
|
|
them as polymorphic functions.</p>
|
|
<p><span class="target" id="design.mps.protocol.int.superclass"></span><a class="mpstag reference internal" href="#design.mps.protocol.int.superclass">.int.superclass:</a> <tt class="docutils literal"><span class="pre">ProtocolClassSuperclassPoly(class)</span></tt> is an
|
|
introspection function which returns the direct superclass of class
|
|
object class.</p>
|
|
<p><span class="target" id="design.mps.protocol.int.static-superclass"></span><a class="mpstag reference internal" href="#design.mps.protocol.int.static-superclass">.int.static-superclass:</a> <tt class="docutils literal"><span class="pre">SUPERCLASS(className)</span></tt> is an
|
|
introspection macro which returns the direct superclass given a class
|
|
name, which must (obviously) be statically known. The macro expands
|
|
into a call to the ensure function for the class name, so this must be
|
|
in scope (which may require a forward declaration). The macro is
|
|
useful for next-method calls (see <a class="reference internal" href="#design.mps.protocol.overview.next-method">.overview.next-method</a>).
|
|
The superclass is returned with type <tt class="xref c c-type docutils literal"><span class="pre">ProtocolClass</span></tt> so it may
|
|
be necessary to cast it to the type for the appropriate subclass.</p>
|
|
<p><span class="target" id="design.mps.protocol.int.static-superclass.special"></span><a class="mpstag reference internal" href="#design.mps.protocol.int.static-superclass.special">.int.static-superclass.special:</a> Implementors of classes which
|
|
are designed to be subclassed without extension may choose to provide
|
|
a convenience macro which expands into a call to <tt class="xref c c-func docutils literal"><span class="pre">SUPERCLASS()</span></tt>
|
|
along with a type cast. For example, there might be a macro for
|
|
finding pool superclasses such that the macro call
|
|
<tt class="docutils literal"><span class="pre">POOL_SUPERCLASS(className)</span></tt> is exactly equivalent to
|
|
<tt class="docutils literal"><span class="pre">(PoolClass)SUPERCLASS(className)</span></tt>. It’s convenient to define these
|
|
macros alongside the convenience class definition macro (see
|
|
<a class="reference internal" href="#design.mps.protocol.int.define-special">.int.define-special</a>).</p>
|
|
<p><span class="target" id="design.mps.protocol.int.class"></span><a class="mpstag reference internal" href="#design.mps.protocol.int.class">.int.class:</a> <tt class="docutils literal"><span class="pre">ClassOfPoly(inst)</span></tt> is an introspection
|
|
function which returns the class of which inst is a direct instance.</p>
|
|
<p><span class="target" id="design.mps.protocol.int.subclass"></span><a class="mpstag reference internal" href="#design.mps.protocol.int.subclass">.int.subclass:</a> <tt class="docutils literal"><span class="pre">IsSubclassPoly(sub,</span> <span class="pre">super)</span></tt> is an
|
|
introspection function which returns a Boolean indicating whether sub
|
|
is a subclass of super. That is, it is a predicate for testing
|
|
subclass relationships.</p>
|
|
</div>
|
|
<div class="section" id="multiple-inheritance">
|
|
<h3>16.6.6. Multiple inheritance<a class="headerlink" href="#multiple-inheritance" title="Permalink to this headline">¶</a></h3>
|
|
<p><span class="target" id="design.mps.protocol.int.mult-inherit"></span><a class="mpstag reference internal" href="#design.mps.protocol.int.mult-inherit">.int.mult-inherit:</a> Multiple inheritance involves an extension
|
|
of the protocol (see <a class="reference internal" href="#design.mps.protocol.int.extend">.int.extend</a>) and also multiple uses
|
|
of the single inheritance mechanism (see
|
|
<a class="reference internal" href="#design.mps.protocol.int.inheritance">.int.inheritance</a>). It also requires specialized methods
|
|
for <tt class="xref c c-func docutils literal"><span class="pre">coerceClass()</span></tt> and <tt class="xref c c-func docutils literal"><span class="pre">coerceInst()</span></tt> to be written (see
|
|
<a class="reference internal" href="#design.mps.protocol.overview.coerce-class">.overview.coerce-class</a> and
|
|
<a class="reference internal" href="#design.mps.protocol.overview.coerce-inst">.overview.coerce-inst</a>). Documentation on support for
|
|
multiple inheritance is under construction. This facility is not
|
|
currently used. The basic idea is described in
|
|
mail.tony.1998-10-06.11-03(0).</p>
|
|
</div>
|
|
<div class="section" id="protocol-guidelines">
|
|
<h3>16.6.7. Protocol guidelines<a class="headerlink" href="#protocol-guidelines" title="Permalink to this headline">¶</a></h3>
|
|
<p><span class="target" id="design.mps.protocol.guide.fail"></span><a class="mpstag reference internal" href="#design.mps.protocol.guide.fail">.guide.fail:</a> When designing an extensible function which
|
|
might fail, the design must permit the correct implementation of the
|
|
failure-case code. Typically, a failure might occur in any method in
|
|
the chain. Each method is responsible for correctly propagating
|
|
failure information supplied by superclass methods and for managing
|
|
it’s own failures.</p>
|
|
<p><span class="target" id="design.mps.protocol.guide.fail.before-next"></span><a class="mpstag reference internal" href="#design.mps.protocol.guide.fail.before-next">.guide.fail.before-next:</a> Dealing with a failure which is
|
|
detected before any next-method call is made is similar to a fail case
|
|
in any non-extensible function. See <a class="reference internal" href="#design.mps.protocol.example.fail">.example.fail</a> below.</p>
|
|
<p><span class="target" id="design.mps.protocol.guide.fail.during-next"></span><a class="mpstag reference internal" href="#design.mps.protocol.guide.fail.during-next">.guide.fail.during-next:</a> Dealing with a failure returned from
|
|
a next-method call is also similar to a fail case in any
|
|
non-extensible function. See <a class="reference internal" href="#design.mps.protocol.example.fail">.example.fail</a> below.</p>
|
|
<p><span class="target" id="design.mps.protocol.guide.fail.after-next"></span><a class="mpstag reference internal" href="#design.mps.protocol.guide.fail.after-next">.guide.fail.after-next:</a> Dealing with a failure which is
|
|
detected after the next methods have been successfully invoked is more
|
|
complex. If this scenario is possible, the design must include an
|
|
“anti-function”, and each class must ensure that it provides a method
|
|
for the anti-method which will clean up any resources which are
|
|
claimed after a successful invocation of the main method for that
|
|
class. Typically the anti-function would exist anyway for clients of
|
|
the protocol (for example, “finish” is an anti-function for “init”).
|
|
The effect of the next-method call can then be cleaned up by calling
|
|
the anti-method for the superclass. See <a class="reference internal" href="#design.mps.protocol.example.fail">.example.fail</a>
|
|
below.</p>
|
|
</div>
|
|
<div class="section" id="example">
|
|
<h3>16.6.8. Example<a class="headerlink" href="#example" title="Permalink to this headline">¶</a></h3>
|
|
<p><span class="target" id="design.mps.protocol.example.inheritance"></span><a class="mpstag reference internal" href="#design.mps.protocol.example.inheritance">.example.inheritance:</a> The following example class definition
|
|
shows both inheritance and specialization. It shows the definition of
|
|
the class <tt class="docutils literal"><span class="pre">EPDRPoolClass</span></tt>, which inherits from <tt class="docutils literal"><span class="pre">EPDLPoolClass</span></tt> and
|
|
has specialized values of the <tt class="docutils literal"><span class="pre">name</span></tt>, <tt class="docutils literal"><span class="pre">init</span></tt>, and <tt class="docutils literal"><span class="pre">alloc</span></tt>
|
|
fields. The type <tt class="docutils literal"><span class="pre">EPDLPoolClass</span></tt> is an alias for
|
|
<tt class="xref c c-type docutils literal"><span class="pre">PoolClass</span></tt>.</p>
|
|
<div class="highlight-c"><div class="highlight"><pre><span class="k">typedef</span> <span class="n">EPDLPoolClass</span> <span class="n">EPDRPoolClass</span><span class="p">;</span>
|
|
<span class="k">typedef</span> <span class="n">EPDLPoolClassStruct</span> <span class="n">EPDRPoolClassStruct</span><span class="p">;</span>
|
|
|
|
<span class="n">DEFINE_CLASS</span><span class="p">(</span><span class="n">EPDRPoolClass</span><span class="p">,</span> <span class="n">this</span><span class="p">)</span>
|
|
<span class="p">{</span>
|
|
<span class="n">INHERIT_CLASS</span><span class="p">(</span><span class="n">this</span><span class="p">,</span> <span class="n">EPDLPoolClass</span><span class="p">);</span>
|
|
<span class="n">this</span><span class="o">-></span><span class="n">name</span> <span class="o">=</span> <span class="s">"EPDR"</span><span class="p">;</span>
|
|
<span class="n">this</span><span class="o">-></span><span class="n">init</span> <span class="o">=</span> <span class="n">EPDRInit</span><span class="p">;</span>
|
|
<span class="n">this</span><span class="o">-></span><span class="n">alloc</span> <span class="o">=</span> <span class="n">EPDRAlloc</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
</div>
|
|
<p><span class="target" id="design.mps.protocol.example.extension"></span><a class="mpstag reference internal" href="#design.mps.protocol.example.extension">.example.extension:</a> The following (hypothetical) example
|
|
class definition shows inheritance, specialization and also extension.
|
|
It shows the definition of the class <tt class="docutils literal"><span class="pre">EPDLDebugPoolClass</span></tt>, which
|
|
inherits from <tt class="docutils literal"><span class="pre">EPDLPoolClass</span></tt>, but also implements a method for
|
|
checking properties of the pool.</p>
|
|
<div class="highlight-c"><div class="highlight"><pre><span class="k">typedef</span> <span class="k">struct</span> <span class="n">EPDLDebugPoolClassStruct</span> <span class="p">{</span>
|
|
<span class="n">EPDLPoolClassStruct</span> <span class="n">epdl</span><span class="p">;</span>
|
|
<span class="n">DebugPoolCheckMethod</span> <span class="n">check</span><span class="p">;</span>
|
|
<span class="n">Sig</span> <span class="n">sig</span><span class="p">;</span>
|
|
<span class="p">}</span> <span class="n">EPDLDebugPoolClassStruct</span><span class="p">;</span>
|
|
|
|
<span class="k">typedef</span> <span class="n">EPDLDebugPoolClassStruct</span> <span class="o">*</span><span class="n">EPDLDebugPoolClass</span><span class="p">;</span>
|
|
|
|
<span class="n">DEFINE_CLASS</span><span class="p">(</span><span class="n">EPDLDebugPoolClass</span><span class="p">,</span> <span class="n">this</span><span class="p">)</span>
|
|
<span class="p">{</span>
|
|
<span class="n">EPDLPoolClass</span> <span class="n">epdl</span> <span class="o">=</span> <span class="o">&</span><span class="n">this</span><span class="o">-></span><span class="n">epdl</span><span class="p">;</span>
|
|
<span class="n">INHERIT_CLASS</span><span class="p">(</span><span class="n">epdl</span><span class="p">,</span> <span class="n">EPDLPoolClass</span><span class="p">);</span>
|
|
<span class="n">epdl</span><span class="o">-></span><span class="n">name</span> <span class="o">=</span> <span class="s">"EPDLDBG"</span><span class="p">;</span>
|
|
<span class="n">this</span><span class="o">-></span><span class="n">check</span> <span class="o">=</span> <span class="n">EPDLDebugCheck</span><span class="p">;</span>
|
|
<span class="n">this</span><span class="o">-></span><span class="n">sig</span> <span class="o">=</span> <span class="n">EPDLDebugSig</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
</div>
|
|
<p><span class="target" id="design.mps.protocol.example.fail"></span><a class="mpstag reference internal" href="#design.mps.protocol.example.fail">.example.fail:</a> The following example shows the implementation
|
|
of failure-case code for an “init” method, making use of the “finish”
|
|
anti-method:</p>
|
|
<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="n">Res</span> <span class="nf">mySegInit</span><span class="p">(</span><span class="n">Seg</span> <span class="n">seg</span><span class="p">,</span> <span class="n">Pool</span> <span class="n">pool</span><span class="p">,</span> <span class="n">Addr</span> <span class="n">base</span><span class="p">,</span> <span class="n">Size</span> <span class="n">size</span><span class="p">,</span>
|
|
<span class="n">Bool</span> <span class="n">reservoirPermit</span><span class="p">,</span> <span class="kt">va_list</span> <span class="n">args</span><span class="p">)</span>
|
|
<span class="p">{</span>
|
|
<span class="n">SegClass</span> <span class="n">super</span><span class="p">;</span>
|
|
<span class="n">MYSeg</span> <span class="n">myseg</span><span class="p">;</span>
|
|
<span class="n">OBJ1</span> <span class="n">obj1</span><span class="p">;</span>
|
|
<span class="n">Res</span> <span class="n">res</span><span class="p">;</span>
|
|
<span class="n">Arena</span> <span class="n">arena</span><span class="p">;</span>
|
|
|
|
<span class="n">AVERT</span><span class="p">(</span><span class="n">Seg</span><span class="p">,</span> <span class="n">seg</span><span class="p">);</span>
|
|
<span class="n">myseg</span> <span class="o">=</span> <span class="n">SegMYSeg</span><span class="p">(</span><span class="n">seg</span><span class="p">);</span>
|
|
<span class="n">AVERT</span><span class="p">(</span><span class="n">Pool</span><span class="p">,</span> <span class="n">pool</span><span class="p">);</span>
|
|
<span class="n">arena</span> <span class="o">=</span> <span class="n">PoolArena</span><span class="p">(</span><span class="n">pool</span><span class="p">);</span>
|
|
|
|
<span class="cm">/* Ensure the pool is ready for the segment */</span>
|
|
<span class="n">res</span> <span class="o">=</span> <span class="n">myNoteSeg</span><span class="p">(</span><span class="n">pool</span><span class="p">,</span> <span class="n">seg</span><span class="p">);</span>
|
|
<span class="k">if</span><span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">ResOK</span><span class="p">)</span>
|
|
<span class="k">goto</span> <span class="n">failNoteSeg</span><span class="p">;</span>
|
|
|
|
<span class="cm">/* Initialize the superclass fields first via next-method call */</span>
|
|
<span class="n">super</span> <span class="o">=</span> <span class="p">(</span><span class="n">SegClass</span><span class="p">)</span><span class="n">SUPERCLASS</span><span class="p">(</span><span class="n">MYSegClass</span><span class="p">);</span>
|
|
<span class="n">res</span> <span class="o">=</span> <span class="n">super</span><span class="o">-></span><span class="n">init</span><span class="p">(</span><span class="n">seg</span><span class="p">,</span> <span class="n">pool</span><span class="p">,</span> <span class="n">base</span><span class="p">,</span> <span class="n">size</span><span class="p">,</span> <span class="n">reservoirPermit</span><span class="p">,</span> <span class="n">args</span><span class="p">);</span>
|
|
<span class="k">if</span><span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">ResOK</span><span class="p">)</span>
|
|
<span class="k">goto</span> <span class="n">failNextMethods</span><span class="p">;</span>
|
|
|
|
<span class="cm">/* Create an object after the next-method call */</span>
|
|
<span class="n">res</span> <span class="o">=</span> <span class="n">ControlAlloc</span><span class="p">(</span><span class="o">&</span><span class="n">obj1</span><span class="p">,</span> <span class="n">arena</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">OBJ1Struct</span><span class="p">),</span> <span class="n">reservoirPermit</span><span class="p">);</span>
|
|
<span class="k">if</span><span class="p">(</span><span class="n">res</span> <span class="o">!=</span> <span class="n">ResOK</span><span class="p">)</span>
|
|
<span class="k">goto</span> <span class="n">failObj1</span><span class="p">;</span>
|
|
|
|
<span class="n">myseg</span><span class="o">-></span><span class="n">obj1</span> <span class="o">=</span> <span class="n">obj1</span>
|
|
<span class="k">return</span> <span class="n">ResOK</span><span class="p">;</span>
|
|
|
|
<span class="nl">failObj1:</span>
|
|
<span class="cm">/* call the anti-method for the superclass */</span>
|
|
<span class="n">super</span><span class="o">-></span><span class="n">finish</span><span class="p">(</span><span class="n">seg</span><span class="p">);</span>
|
|
<span class="nl">failNextMethods:</span>
|
|
<span class="cm">/* reverse the effect of myNoteSeg */</span>
|
|
<span class="n">myUnnoteSeg</span><span class="p">(</span><span class="n">pool</span><span class="p">,</span> <span class="n">seg</span><span class="p">);</span>
|
|
<span class="nl">failNoteSeg:</span>
|
|
<span class="k">return</span> <span class="n">res</span><span class="p">;</span>
|
|
<span class="p">}</span>
|
|
</pre></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="section" id="implementation">
|
|
<h2>16.7. Implementation<a class="headerlink" href="#implementation" title="Permalink to this headline">¶</a></h2>
|
|
<p><span class="target" id="design.mps.protocol.impl.derived-names"></span><a class="mpstag reference internal" href="#design.mps.protocol.impl.derived-names">.impl.derived-names:</a> The <tt class="xref c c-func docutils literal"><span class="pre">DEFINE_CLASS()</span></tt> macro derives
|
|
some additional names from the class name as part of it’s
|
|
implementation. These should not appear in the source code - but it
|
|
may be useful to know about this for debugging purposes. For each
|
|
class definition for class <tt class="docutils literal"><span class="pre">SomeClass</span></tt>, the macro defines the
|
|
following:</p>
|
|
<p><tt class="docutils literal"><span class="pre">extern</span> <span class="pre">SomeClass</span> <span class="pre">EnsureSomeClass(void);</span></tt></p>
|
|
<blockquote>
|
|
<div>The class accessor function. See <a class="reference internal" href="#design.mps.protocol.overview.naming">.overview.naming</a>.</div></blockquote>
|
|
<p><tt class="docutils literal"><span class="pre">static</span> <span class="pre">Bool</span> <span class="pre">protocolSomeClassGuardian;</span></tt></p>
|
|
<blockquote>
|
|
<div>A Boolean which indicates whether the class has been initialzed yet.</div></blockquote>
|
|
<p><tt class="docutils literal"><span class="pre">static</span> <span class="pre">void</span> <span class="pre">protocolEnsureSomeClass(SomeClass);</span></tt></p>
|
|
<blockquote>
|
|
<div>A function called by <tt class="docutils literal"><span class="pre">EnsureSomeClass</span></tt>. All the class
|
|
initialization code is actually in this function.</div></blockquote>
|
|
<p><tt class="docutils literal"><span class="pre">static</span> <span class="pre">SomeClassStruct</span> <span class="pre">protocolSomeClassStruct;</span></tt></p>
|
|
<blockquote>
|
|
<div>Static storage for the canonical class object.</div></blockquote>
|
|
<p><span class="target" id="design.mps.protocol.impl.init-once"></span><a class="mpstag reference internal" href="#design.mps.protocol.impl.init-once">.impl.init-once:</a> Class objects only behave according to their
|
|
definition after they have been initialized, and class protocols may
|
|
not be used before initialization has happened. The only code which is
|
|
allowed to see a class object in a partially initialized state is the
|
|
initialization code itself – and this must take care not to pass the
|
|
object to any other code which might assume it is initialized. Once a
|
|
class has been initialized, the class might have a client. The class
|
|
must not be initialized again when this has happened, because the
|
|
state is not necessarily consistent in the middle of an initialization
|
|
function. The initialization state for each class is stored in a
|
|
Boolean “guardian” variable whose name is derived from the class name
|
|
(see <a class="reference internal" href="#design.mps.protocol.impl.derived-names">.impl.derived-names</a>). This ensures the
|
|
initialization happens only once. The path through the
|
|
<tt class="docutils literal"><span class="pre">EnsureSomeClass</span></tt> function should be very fast for the common case
|
|
when this variable is <tt class="docutils literal"><span class="pre">TRUE</span></tt>, and the class has already been
|
|
initialized, as the canonical static storage can simply be returned in
|
|
that case. However, when the value of the guardian is <tt class="docutils literal"><span class="pre">FALSE</span></tt>, the
|
|
class is not initialized. In this case, a call to <tt class="docutils literal"><span class="pre">EnsureSomeClass</span></tt>
|
|
must first execute the initialization code and then set the guardian
|
|
to <tt class="docutils literal"><span class="pre">TRUE</span></tt>. However, this must happen atomically (see
|
|
<a class="reference internal" href="#design.mps.protocol.impl.init-lock">.impl.init-lock</a>).</p>
|
|
<p><span class="target" id="design.mps.protocol.impl.init-lock"></span><a class="mpstag reference internal" href="#design.mps.protocol.impl.init-lock">.impl.init-lock:</a> There would be the possibility of a race
|
|
condition if <tt class="docutils literal"><span class="pre">EnsureSomeClass</span></tt> were called concurrently on separate
|
|
threads before <tt class="docutils literal"><span class="pre">SomeClass</span></tt> has been initialized. The class must not
|
|
be initialized more than once, so the sequence test-guard, init-class,
|
|
set-guard must be run as a critical region. It’s not sufficient to use
|
|
the arena lock to protect the critical region, because the class
|
|
object might be shared between multiple arenas. The
|
|
<tt class="xref c c-func docutils literal"><span class="pre">DEFINE_CLASS()</span></tt> macro uses a global recursive lock instead. The
|
|
lock is only claimed after an initial unlocked access of the guard
|
|
variable shows that the class is not initialized. This avoids any
|
|
locking overhead for the common case where the class is already
|
|
initialized. This lock is provided by the lock module – see
|
|
design.mps.lock(0).</p>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="sphinxsidebar">
|
|
<div class="sphinxsidebarwrapper">
|
|
<p class="logo"><a href="../index.html">
|
|
<img class="logo" src="../_static/logo.png" alt="Logo"/>
|
|
</a></p>
|
|
<h3><a href="../index.html">Table Of Contents</a></h3>
|
|
<ul>
|
|
<li><a class="reference internal" href="#">16. Protocol inheritance</a><ul>
|
|
<li><a class="reference internal" href="#introduction">16.1. Introduction</a></li>
|
|
<li><a class="reference internal" href="#history">16.2. History</a></li>
|
|
<li><a class="reference internal" href="#purpose">16.3. Purpose</a></li>
|
|
<li><a class="reference internal" href="#requirements">16.4. Requirements</a></li>
|
|
<li><a class="reference internal" href="#overview">16.5. Overview</a></li>
|
|
<li><a class="reference internal" href="#interface">16.6. Interface</a><ul>
|
|
<li><a class="reference internal" href="#class-definition">16.6.1. Class definition</a></li>
|
|
<li><a class="reference internal" href="#single-inheritance">16.6.2. Single inheritance</a></li>
|
|
<li><a class="reference internal" href="#specialization">16.6.3. Specialization</a></li>
|
|
<li><a class="reference internal" href="#extension">16.6.4. Extension</a></li>
|
|
<li><a class="reference internal" href="#introspection">16.6.5. Introspection</a></li>
|
|
<li><a class="reference internal" href="#multiple-inheritance">16.6.6. Multiple inheritance</a></li>
|
|
<li><a class="reference internal" href="#protocol-guidelines">16.6.7. Protocol guidelines</a></li>
|
|
<li><a class="reference internal" href="#example">16.6.8. Example</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a class="reference internal" href="#implementation">16.7. Implementation</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
<h4>Previous topic</h4>
|
|
<p class="topless"><a href="object-debug.html"
|
|
title="previous chapter">15. Debugging features for client objects</a></p>
|
|
<h4>Next topic</h4>
|
|
<p class="topless"><a href="type.html"
|
|
title="next chapter">17. General MPS types</a></p><h4>Downloads</h4>
|
|
|
|
<p class="topless">
|
|
<a href="http://www.ravenbrook.com/project/mps/release/1.111.0/">MPS Kit release 1.111.0</a><br>
|
|
<a href="http://www.ravenbrook.com/project/mps/release/">All MPS Kit releases</a>
|
|
</p>
|
|
|
|
<h4>Issues</h4>
|
|
|
|
<p class="topless">
|
|
<a href="http://www.ravenbrook.com/project/mps/issue/?action=list&view=status%3dopen&display=Job:Priority:Title&sort=Priority">Known issues</a><br>
|
|
<a href="http://www.ravenbrook.com/project/mps/issue/?action=fixed&release_fixed=1.111.0">Issues fixed in release 1.111.0</a>
|
|
</p><h4>Contact us</h4>
|
|
|
|
<p class="topless"><a href="mailto:mps-questions@ravenbrook.com">mps-questions@ravenbrook.com</a></p>
|
|
</div>
|
|
</div>
|
|
<div class="clearer"></div>
|
|
</div>
|
|
<div class="related">
|
|
<h3>Navigation</h3>
|
|
<ul>
|
|
<li class="right" style="margin-right: 10px">
|
|
<a href="../genindex.html" title="General Index"
|
|
>index</a></li>
|
|
<li class="right" >
|
|
<a href="type.html" title="17. General MPS types"
|
|
>next</a> |</li>
|
|
<li class="right" >
|
|
<a href="object-debug.html" title="15. Debugging features for client objects"
|
|
>previous</a> |</li>
|
|
<li><a href="../index.html">Memory Pool System 1.111.0 documentation</a> »</li>
|
|
<li><a href="index.html" >Design</a> »</li>
|
|
</ul>
|
|
</div>
|
|
<div class="footer">
|
|
© <a href="../copyright.html">Copyright</a> 2013, Ravenbrook Limited.
|
|
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3.
|
|
</div>
|
|
</body>
|
|
</html> |