summaryrefslogtreecommitdiff
path: root/doc/extlvals.htm
blob: 22290670cfaefeb40829894569b4d63e87502656 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
    <TITLE>Icon External Values</TITLE>
    <LINK REL="STYLESHEET" TYPE="text/css" HREF="istyle.css">
    <LINK REL="SHORTCUT ICON" HREF="shortcut.gif">
</HEAD>
<BODY>

<P><A HREF="http://www.cs.arizona.edu/icon/"> <IMG SRC="wwwcube.gif"
ALT="[Icon home]" WIDTH=128 HEIGHT=144 BORDER=0 ALIGN=RIGHT> </A>

<H1> Icon External Values </H1>

<P> Carl Sturtivant
<BR> <SMALL> Computer Science &amp; Engineering Department </SMALL>
<BR> <SMALL> University of Minnesota </SMALL>

<P> Gregg M. Townsend
<BR> <SMALL> Department of Computer Science </SMALL>
<BR> <SMALL> The University of Arizona </SMALL>

<P> <SMALL> www.cs.arizona.edu/icon/v950/extlvals.htm
<BR> 
Last updated March 25, 2010</SMALL>
<!-- $Id: extlvals.htm,v 1.18 2010/03/25 23:33:10 gmt Exp $ -->


<H2> Introduction </H2>


<P> External values provide a way for
<A HREF="cfuncs.htm">dynamically loaded C functions</A>
to create and return opaque data structures to an Icon program.
This allows state to be maintained across multiple calls of
loaded functions.

<P> The creation of an external value in C defines 
not just the data itself but also some related attributes.
These control the sorting behavior, image, and other such aspects.
Icon provides defaults and also adds a serial number
similar to those of lists, sets, and tables.

<P> The specification of attributes effectively creates a number
of distinct types.
Each loadable library can define the types it needs for its own purposes.
From an object-oriented perspective, these can be seen as subtypes
of a common <CODE>external</CODE> type.


<H2> External Values in an Icon Program </H2>

<P> External values are opaque to Icon. They are <EM>created</EM> only by
dynamically 
loaded C functions, any of which in turn may have access to their internals. In 
this way a library of Icon functions to work with a specific kind of external 
value is possible. However, such values can be seen and manipulated (assigned, 
passed to procedures or functions, sorted, copied, etc.) in Icon. The 
behavior of an external value in Icon may be modified to some extent by the 
implementation of the dynamically loaded function that is used to create it, as 
described below.

<P> In what follows let <CODE>E</CODE>, <CODE>E1</CODE>, and <CODE>E2</CODE>
be external values
produced by some loaded function or functions. Icon prescribes the following 
default behavior of such values, which is exhibited if the functions that 
created them did not override such at the time of creation. Otherwise behavior 
in the following contexts is determined by the external values' creators.

<P> External values always sort after values of all other types.
Within themselves external 
values are first sorted by type name (which is a set by the creator,
is returned by the Icon function <CODE>type</CODE>,
and specifies a subtype of the external type).
The default sort within such a subtype is by serial number. Only sorting 
within a subtype (i.e., externals with a specific type name) can be overridden 
by the creator. See the next section for a description of the relevant C 
internals. The default behavior follows.

<BLOCKQUOTE><DL>
<DT><CODE>type(E)</CODE>
	<DD>returns the string <CODE>"external"</CODE>
<DT><CODE>image(E)</CODE>
	<DD>returns a string indicating the type, serial number,
	and the number of data words,
	<I>e.g.</I> <CODE>"external_12(3)"</CODE>
<DT><CODE>copy(E)</CODE>
	<DD>returns <CODE>E</CODE> itself without copying
<DT><CODE>sort()</CODE>
	<DD>external values sort first by type name and then by serial number
<DT><CODE>E1 === E2</CODE>	
	<DD>produces <CODE>E1</CODE> when <CODE>E1</CODE> and <CODE>E2</CODE>
	are the same external object; otherwise fails
<DT><CODE>E1 ~=== E2</CODE>
	<DD>produces <CODE>E2</CODE> when <CODE>E1</CODE> and <CODE>E2</CODE>
	are distinct; otherwise fails
</DL></BLOCKQUOTE>
	
	
<H2> Creating and Using External Values in C </H2>

<P>These next sections describe the C interface for a reader who is
familiar with the use of loadable functions.

<P> An Icon external value is implemented by a descriptor that points
to an external block containing several components.
The data area and the function list are the most important of these.

<P> An integer word count indicates the size of the data area.
This is specified when the external block is created.
Often external data is a single pointer to other data (a handle)
and so only one word is required.

<P> The function list allows the programmer to override,
for all values of the same external type,
the default behaviors listed in the previous section.
The list is a callback table pointing to programmer-defined C functions
as described in more detail below.
The function list also acts as a unique type identifier, because external
values with different function lists behave as values of distinct type.

<P> A dynamically loaded C function allocates an external value by including
<CODE>ipl/cfuncs/icall.h</CODE> and calling <CODE>alcexternal</CODE>:

<BLOCKQUOTE>
<DL>
<DT>
<CODE>externalblock *alcexternal</CODE>(long size, funclist *funcs, void *data)
</DT><DD>
    allocates and returns a pointer to an external block.
    <BR><VAR>size</VAR> specifies the number of bytes
    in the entire external block (and by implication 
    the size of the data block inside it).
    <BR><VAR>funcs</VAR>, if not null, specifies a list of functions to
    override the default behavior.  See the next section.
    <BR><VAR>data</VAR>, if not null, specifies the location of data
    that is copied in to initialize the data block (until it is full).
</DD></DL>
</BLOCKQUOTE>

<P>
A typical call might be
<BLOCKQUOTE>
    blk = alcexternal(sizeof(externalblock) + sizeof(mydata), funcs, &mydata); 
</BLOCKQUOTE>
The result is returned to Icon by the macro call
<CODE>RetExternal(</CODE>blk<CODE>)</CODE>.
The block may eventually be freed by garbage collection if it
is not saved or if it later becomes inaccessible to the Icon program.

<P> A loadable function that accepts an external value as an argument can call
<BLOCKQUOTE>
    ArgExternal(i,f);
</BLOCKQUOTE>
to validate argv[i] as an external value of the type associated
with function list f, and can then call
<BLOCKQUOTE>
    blk = ExternalBlock(i);
</BLOCKQUOTE>
to get the address of the associated external block;
the associated data is at blk&ndash;&gt;data.

<P>A more complete example is found in the file
<CODE>ipl/cfuncs/external.c</CODE>.

	
<H2> The Function List Passed to alcexternal </H2>

<P> The function list associated with an external value is a struct
containing pointers to C functions.
It is reminiscent of a "dispatch table" or "class pointer" 
for dynamic method calls in an implementation of an object oriented programming 
language. Indeed an Icon external value is very much like a traditional object 
with its own data and methods. Typically such a function list would be static 
and shared among many Icon external values of the same kind ("class" or "type").

<P> Every external value has a function list; a default list is supplied
if NULL is passed to alcexternal.  A null entry within a function list
produces the default behavior for the associated action.

<P> Functions in the list use the same interface as loadable C functions.
Incoming arguments are passed beginning at argv[1].
A result is produced by storing it in argv[0]
and returning 0 as the outcome of the function.
When extlcmp is called, argc has a value of 2;
for the other functions, argc is 1.

<P> The possible custom functions are as follows:

<BLOCKQUOTE>
<DL>

<DT>
<CODE>int extlcmp</CODE>(int argc, descriptor *argv)	
</DT><DD>
returns an Icon integer
for use in sorting two external values that both have this function list
and are therefore considered to be of the same external subtype.
The function result should be negative if the first external value is
deemed less than the second, zero if they are deemed equal, and positive
if the first is deemed greater than the second.
This overrides the default behavior of the <CODE>sort</CODE> function
which compares serial numbers.
</DD>

<DT>
<CODE>int extlcopy</CODE>(int argc, descriptor *argv)
</DT><DD>
returns an external value defined as a copy of its argument. 
This overrides the default behavior of the <CODE>copy</CODE> function,
which is to return another reference to the external value without copying.
</DD>

<DT>
<CODE>int extlname</CODE>(int argc, descriptor *argv)
</DT><DD>
returns an Icon string naming the type of the external value.
This overrides the default behavior of the <CODE>type</CODE> function, and thus
also affects the ordering relative to other external values when sorting.
</DD>

<DT>
<CODE>int extlimage</CODE>(int argc, descriptor *argv)
</DT><DD>
returns an Icon string to serve as the image of the external value.
This overrides the default behavior of the <CODE>image</CODE> function.
</DD>

</DL>
</BLOCKQUOTE>
	

<H2> Implementation Details </H2>

<SMALL>This section supplements the Icon
<A HREF="http://www.cs.arizona.edu/icon/ibsale.htm">
implementation book</A>.</SMALL>

<P> A descriptor for an external value has a vword containing the bit pattern 
D_External which contains the value T_External indicating the external type, 
along with the bit F_Nqual indicating that the value is not a string and the 
bit F_Ptr indicating to the garbage collector that the dword is a pointer that 
needs tending. The dword contains a pointer to an external block. This block is 
implemented as a C struct with a pointer to a function block C struct as 
follows. The structs below, along with types word and descriptor,
are defined in ipl/cfuncs/icall.h.
	
<PRE>
typedef struct funclist {	 /* list of user defined callbacks */
	int (*extlcmp)   (int argc, descriptor *argv);	/* compare */
	int (*extlcopy)  (int argc, descriptor *argv);	/* copy */
	int (*extlname)  (int argc, descriptor *argv);	/* type name */
	int (*extlimage) (int argc, descriptor *argv);	/* image */
} funclist;	

typedef struct externalblock {
	word title;		/* the block header, including type */
	word size;		/* the number of bytes in the block */
	word id;		/* the serial number */
	funclist *funcs;	/* pointer to the callback list */
	word data[];		/* arbitrary custom data */
} externalblock;
</PRE>

<P> A call of alcexternal initializes all fields of an external block.
Data is copied without interpretation, and the function
list pointer is stored.  The header is assigned an appropriate constant for the 
garbage collector, and the size is set. alcexternal maintains a static 
count of the number of external blocks allocated, and this is incremented and 
assigned to id.

<P> The following error code numbers are assigned for use with external values:
<BLOCKQUOTE><TABLE>
<TR><TH>errno<TH>errtext<TH>meaning
<TR><TD><CODE>131</CODE><TD><CODE>external expected</CODE>
    <TD>not an external value
<TR><TD><CODE>132</CODE><TD><CODE>incorrect external type</CODE>
    <TD>external of wrong flavor
<TR><TD><CODE>133</CODE><TD><CODE>invalid external value</CODE>
    <TD>right flavor in wrong context
<TR><TD><CODE>134</CODE><TD><CODE>malformed external value</CODE>
    <TD>data is bogus, not just inappropriate
</TABLE></BLOCKQUOTE>

<P> <HR>

</BODY>
</HTML>