Page Menu
Home
Xreate
Search
Configure Global Search
Log In
Docs
Questions
Repository
Issues
Patches
Internal API
Files
F2730389
context.xml
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Fri, Mar 13, 10:49 PM
Size
11 KB
Mime Type
text/xml
Expires
Sun, Mar 15, 10:49 PM (1 d, 16 h)
Engine
blob
Format
Raw Data
Handle
243489
Attached To
rXR Xreate
context.xml
View Options
<?xml version="1.0" encoding="UTF-8"?>
<chapter version="5.1" xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xila="http://www.w3.org/2001/XInclude/local-attributes"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:trans="http://docbook.org/ns/transclusion"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:m="http://www.w3.org/1998/Math/MathML"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://docbook.org/ns/docbook">
<?xxe-sn 2ahi4rjnvuo 1?>
<title><?xxe-sn 2ahi4rjnvuo 2?>Context</title>
<para><?xxe-sn 2ahi4rjnvuo 3?>Computer program, its internal states and
transitions between them can be looked at from two different sides: control
flow and data flow. This chapter expands on a specific mechanism called
<emphasis><?xxe-sn 2fkjzaz3pq8 1?>context</emphasis> to reflect control flow
as well as a program's structure to facilitate optimizations, safety
measures and supporting code. In simpler terms it is a tool to adjust a
<emphasis><?xxe-sn 2fobxtahb0g 1?>service</emphasis> to serve the best
particular needs of <emphasis><?xxe-sn 2fobxtahb0g 2?>clients</emphasis>
that actually use it.</para>
<para><?xxe-sn 2ahi4rjnvuo b?>Block level annotations are used to define
context and to reason about it. See <link
xlink:href="/d/transcend/#code-blocks-and-context"><?xxe-sn 2ahi4rjnvuo c?>syntax</link>.</para>
<section>
<?xxe-sn 2ahi4rjnvuo d?>
<title><?xxe-sn 2ahi4rjnvuo e?>Examples of Context Usage: Suggestions and
Requirements</title>
<para><?xxe-sn 2fkjzaz3pq8 2?>Context can be used to convey various forms
of information as shown in a few examples below.</para>
<programlisting xml:id="Examples_1"><?xxe-sn 2ahi4rjnvuo f?>name="tests/latex.cpp: Latex.Doc_Examples1"
//someStringFn = function:: string {...}
main = function:: string; entry
{
context:: env(utf8).
someStringFn()
}</programlisting>
<para><?xxe-sn 2ahi4rjnvuo g?>In this example the <code><?xxe-sn 2fkjzaz3pq8 3?>env(utf8)</code>
annotation conveys some information about a code block distinguishing it
from others, which allows to apply specific compilation rules for this
block. Suppose <code><?xxe-sn 2ahi4rjnvuo i?>someStringFn</code> has
different specializations for different environments. Now it's possible to
invoke a specialization tailored for the UTF-8 environment. In this case a
context can be viewed as a <emphasis><?xxe-sn 2axopn9e3uo 2?>suggestion</emphasis>
to pick up an appropriate specialization.</para>
<para><?xxe-sn 2ahi4rjnvuo j?>On the other hand, there is a possibility to
define expected properties of a context:</para>
<programlisting xml:id="Examples_2"><?xxe-sn 2ahi4rjnvuo k?>name="tests/latex.cpp: Latex.Doc_Examples2"
guard:: only_safe_env
{
crucialOperation = function:: bool
{true}
}
main = function:: bool; entry
{
context:: env(safe).
crucialOperation()
}</programlisting>
<para><?xxe-sn 2ahi4rjnvuo l?>Function <code><?xxe-sn 2ahi4rjnvuo m?>crucialOperation</code>
has only one specialization <code><?xxe-sn 2ahi4rjnvuo n?>only_safe_env</code>
in the example. If the context does not provide the required environment
<code><?xxe-sn 2ahi4rjnvuo o?>env(safe)</code> the compiler can't find an
appropriate specialization and reports a compilation error. This is a way
for a function to express <emphasis><?xxe-sn 2axopn9e3uo 3?>requirements</emphasis>
or a contract to a context it works within.</para>
</section>
<section>
<?xxe-sn 2ahi4rjnvuo q?>
<title><?xxe-sn 2ahi4rjnvuo r?>Context Propagation</title>
<para><?xxe-sn 2ahi4rjnvuo s?><emphasis><?xxe-sn 2axopn9e3uo 4?>Context
propagation</emphasis> means that contexts of different blocks are related
reflecting control flow. Context of a particular code block consists of
the following:</para>
<itemizedlist>
<?xxe-sn 2axopn9e3uo 5?>
<listitem>
<?xxe-sn 2axopn9e3uo 6?>
<para><?xxe-sn 2axopn9e3uo 7?>Local context: annotations that are
defined within the block.</para>
</listitem>
<listitem>
<?xxe-sn 2axopn9e3uo 8?>
<para><?xxe-sn 2axopn9e3uo 9?>Parent context. Block's context inherits
context of its parent block reflecting <emphasis><?xxe-sn 2fq6kae5o8w 6?>enclosing
- nested</emphasis> code blocks relation.</para>
</listitem>
<listitem>
<?xxe-sn 2axopn9e3uo a?>
<para><?xxe-sn 2axopn9e3uo b?>Client context. Block's context inherits
a caller's context reflecting clients of a particular function or
<emphasis><?xxe-sn 2fkjzaz3pq8 5?>caller-callee</emphasis> relation.
It allows to take into account how functions are used.</para>
</listitem>
</itemizedlist>
<para><?xxe-sn 2ahi4rjnvuo u?>An example below:</para>
<programlisting xml:id="ContextPropagation1"><?xxe-sn 2ahi4rjnvuo w?>name="tests/latex.cpp: Latex.Doc_ContextPropagation1"
//requires 'safe' context
guard:: only_safe_env
{
crucialOperation = function(a:: int, b::int):: int
{ 0 }
}
test = function:: int; entry {
//blockA
context:: env(safe).
range = [1..10]:: [int].
loop fold(range->x::int, 0->acc):: int {
//blockB
crucialOperation(x, acc)
}
} </programlisting>
<para><?xxe-sn 2ahi4rjnvuo x?>demonstrates context propagation. There are
no compilation errors for the context of <code><?xxe-sn 2fkjzaz3pq8 6?>blockB</code>
contains inherited property <code><?xxe-sn 2fkjzaz3pq8 7?>env(safe)</code>
defined in <code><?xxe-sn 2fkjzaz3pq8 8?>blockA</code>.</para>
<para><?xxe-sn 2ahi4rjnvuo 12?>Another case is when a callee inherits a
caller's context. The example below demonstrates this:</para>
<programlisting xml:id="ContextPropagation2"><?xxe-sn 2ahi4rjnvuo 14?>name="tests/latex.cpp: Latex.Doc_ContextPropagation2", lines=15
guard:: units(mm)
{
lengthToSI = function(x:: float):: int
{ x / 1000 }
}
guard:: units(min)
{
timeToSI = function(x:: float):: int
{ x * 60 }
}
guard:: units(m, sec)
{
velocityToEnv = function(x:: float):: int
{ x }
}
calculateVelocity = function(length:: float, time:: float):: float
{
velocity_si = lengthToSI(length) / timeToSI(time).
velocityToEnv(velocity_si)
}
test = function:: int; entry
{
context:: length(units(mm)); time(units(min)); velocity(units(m, sec)).
calculate(10, 2)
} </programlisting>
<para><?xxe-sn 2ahi4rjnvuo 15?>Function <code><?xxe-sn 2ahi4rjnvuo 16?>calculateVelocity()</code>
works with values measured in different units. It normalizes each value by
invoking the <code><?xxe-sn 2ahi4rjnvuo 17?>..toSI()</code> functions;
after the computation is done it converts the result back to an
environment's units. One approach is to keep unit information for each
variable independently. But if we know that an entire program or a part of
it works only with specific units we can register it in a context, such as
<code><?xxe-sn 2ahi4rjnvuo 18?>length(units(mm))</code> in this example,
letting the function <code><?xxe-sn 2ahi4rjnvuo 19?>calculateVelocity()</code>
and its callees to inherit the context, thus allowing the compiler to
generate code tailored to specific units only.</para>
</section>
<section>
<?xxe-sn 2ahi4rjnvuo 1m?>
<title><?xxe-sn 2ahi4rjnvuo 1n?>Latex (Late Context)</title>
<para><?xxe-sn 2ahi4rjnvuo 1o?>Importance of context as a development tool
stems from the fact that if reflects among other thing a code's clients -
by whom a given code is used. This allows to tailor a service based on
specific clients' needs. Unfortunately this sort of information cannot be
gathered fully at compile time. Compile time or static context reasoning
is <emphasis><?xxe-sn 2ahi4rjnvuo 1p?>partial</emphasis> in a sense that
it is capable of inferring only properties that are true for all possible
paths leading in a CFG to a given block. Beyond that are properties that
depend on an exact path in a CFG. Such uncertainty is possible to resolve
only at runtime once it's known which path exactly is chosen. If a
function is called from different locations, with each location having a
different context, the context of the function in question is obviously
different during each invocation. To solve this problem
<emphasis><?xxe-sn 2axopn9e3uo 11?>late context</emphasis> (latex, in
short) is introduced - a mechanism of embedding into compiled code certain
instructions to gather data on relevant occasions at runtime to determine
an exact or <emphasis><?xxe-sn 2axopn9e3uo 12?>strong</emphasis>
context.</para>
<para><?xxe-sn 2ahi4rjnvuo 1s?>Latex approach can be described as
follows:</para>
<itemizedlist>
<?xxe-sn 2ahi4rjnvuo 1t?>
<listitem>
<?xxe-sn 2ahi4rjnvuo 1u?>
<para><?xxe-sn 2ahi4rjnvuo 1v?>A cloud of all possible context
facts(<emphasis><?xxe-sn 2fobxtahb0g 3?>weak</emphasis> context) for a
given block is computed during compile time. Each such fact is
associated with code paths it is held for.</para>
</listitem>
<listitem>
<?xxe-sn 2axopn9e3uo 13?>
<para><?xxe-sn 2axopn9e3uo 14?>During execution the information is
gathered which facts are hold depending on an actual code path. There
are late parameters reserved to store late context. To pass on latex
parameters, they are injected into functions as hidden
parameters.</para>
</listitem>
<listitem>
<?xxe-sn 2ahi4rjnvuo 1y?>
<para><?xxe-sn 2ahi4rjnvuo 1z?>Late parameters are used internally to
match against guards to determine which specialization to
invoke.</para>
</listitem>
</itemizedlist>
<para><?xxe-sn 2fobxtahb0g 4?>An example:</para>
<programlisting xml:id="Latex1"><?xxe-sn 2ahi4rjnvuo 24?>name="tests/latex.cpp: Latex.Doc_Latex1", lines=15
import raw ("scripts/cfa/context.lp"). //enable context reasoning
guard:: sum
{
compute = function(arg1:: int, arg2:: int):: int
{
arg1 + arg2
}
}
guard:: sub
{
compute = function(arg1:: int, arg2:: int):: int
{
arg1 - arg2
}
}
executeComputation= function(arg1:: int, arg2:: int):: int
{
compute(arg1, arg2) //`compute` has several specializations
}
test = function(cmnd:: int, arg1:: int, arg2:: int):: int; entry
{
if (cmnd > 0)::int
{
//scopeA
context:: sum.
executeComputation(arg1, arg2)
} else
{
//scopeB
context:: sub.
executeComputation(arg1, arg2)
}
}</programlisting>
<para><?xxe-sn 2ahi4rjnvuo 25?>Function <code><?xxe-sn 2fq6kae5o8w 1?>executeComputation</code>
is used in different contexts in scopes <code><?xxe-sn 2fq6kae5o8w 4?>scopeA</code>,
<code><?xxe-sn 2fq6kae5o8w 5?>scopeB</code>, thus it is impossible to
infer statically which <code><?xxe-sn 2fq6kae5o8w 2?>compute</code> 's
specialisation it should invoke. In this case <code><?xxe-sn 2fq6kae5o8w 3?>executeComputation</code>
function's signature is expanded to take in a hidden late parameter with
its value conveying an actual context in order to dynamically invoke an
appropriate specialization at run time.</para>
</section>
</chapter>
Event Timeline
Log In to Comment