Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /sml/trunk/src/ml-nlffi-lib/c.sig
ViewVC logotype

Annotation of /sml/trunk/src/ml-nlffi-lib/c.sig

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1078 - (view) (download) (as text)

1 : blume 828 (*
2 :     * Encoding the C type system in SML.
3 :     *
4 :     * (C) 2001, Lucent Technologies, Bell Laboratories
5 :     *
6 :     * author: Matthias Blume
7 :     *)
8 :     signature C = sig
9 :    
10 : blume 1015 exception OutOfMemory
11 :    
12 : blume 828 (* objects of type 't, constness 'c;
13 :     * The 't type variable will be instantiated with the object's "witness"
14 :     * type. The intention is that there be an isomorphism between such
15 :     * witness types and corresponding C types.
16 :     *
17 :     * Witness types are often the same as the (abstract) type of the value
18 :     * stored in the object. However, this is merely a coincidence. For
19 :     * example, a constant object holding a pointer to a read-write integer
20 : blume 840 * would have type ((sint, rw) ptr, ro) obj and the value itself has
21 :     * type (sint, rw) ptr.
22 : blume 828 * However, in the case of the "light" version of this object (see below),
23 : blume 840 * the object type is ((sint, rw) ptr, ro) obj' while fetching
24 :     * from this object gives a value of type (sint, rw) ptr'.
25 : blume 828 * (In other words, we use the "heavy" versions of value types as witness
26 :     * types -- even in the "light" case.) *)
27 : blume 837 type ('t, 'c) obj
28 : blume 828
29 : blume 975 (* an alternative "light-weight" version that does not carry RTTI at
30 :     * the cost of requiring explicit passing of RTTI for certain operations *)
31 : blume 1031 eqtype ('t, 'c) obj'
32 : blume 828
33 :     (* constness property, to be substituted for 'c *)
34 : blume 840 type ro and rw
35 : blume 828
36 : blume 1078 (* Pointers come in two varieties in C: Pointers to things we
37 :     * know and pointers to "incomplete" types. The "ptr" type constructor
38 :     * below encodes both kinds using the following convention:
39 :     * - in the case of complete target types, 'o will be instantiated
40 :     * to some ('t, 'c) obj
41 :     * - in the case of incomplete target types, 'o will be instantiated
42 :     * to some fresh (abstract) type (see iptr.sig for what this will
43 :     * look like in practice)
44 :     *)
45 :     type 'o ptr (* pointer to 'o *)
46 : blume 836 type ('t, 'n) arr (* 'n-sized array with 't elements *)
47 : blume 828
48 :     (* light-weight alternative *)
49 : blume 1078 eqtype 'o ptr'
50 : blume 828
51 : blume 1078 eqtype void (* no values, admits equality *)
52 :    
53 :     (* void* is really a base type, but it happens to take the
54 :     * form of a light-weight pointer type (with an abstract target).
55 :     * This design makes it possible to use those ptr-related
56 :     * functions that "make sense" for void*. *)
57 :     type voidptr = void ptr' (* C's void* *)
58 :    
59 :     (* function pointers *)
60 : blume 828 type 'f fptr (* a function pointer *)
61 :    
62 :     (* alt *)
63 : blume 1031 eqtype 'f fptr'
64 : blume 828
65 :     (* structures and unions *)
66 :     type 'tag su (* struct/union named 'tag;
67 :     * 'tag is drawn from the types
68 :     * defined in the Tag module *)
69 :    
70 :     (* primtypes (signed/unsigned char, int, short, long; float, double) *)
71 : blume 1031 eqtype schar and uchar
72 :     eqtype sint and uint
73 :     eqtype sshort and ushort
74 :     eqtype slong and ulong
75 :     type float and double
76 : blume 828
77 : blume 1078 (* going from abstract to concrete and vice versa;
78 :     * (this shouldn't be needed except when calling functions through
79 :     * function pointers) *)
80 : blume 828 structure Cvt : sig
81 :     (* ML -> C *)
82 : blume 1036 val c_schar : MLRep.Signed.int -> schar
83 :     val c_uchar : MLRep.Unsigned.word -> uchar
84 :     val c_sint : MLRep.Signed.int -> sint
85 :     val c_uint : MLRep.Unsigned.word -> uint
86 :     val c_sshort : MLRep.Signed.int -> sshort
87 :     val c_ushort : MLRep.Unsigned.word -> ushort
88 :     val c_slong : MLRep.Signed.int -> slong
89 :     val c_ulong : MLRep.Unsigned.word -> ulong
90 :     val c_float : MLRep.Real.real -> float
91 :     val c_double : MLRep.Real.real -> double
92 : blume 828
93 :     (* C -> ML *)
94 : blume 1036 val ml_schar : schar -> MLRep.Signed.int
95 :     val ml_uchar : uchar -> MLRep.Unsigned.word
96 :     val ml_sint : sint -> MLRep.Signed.int
97 :     val ml_uint : uint -> MLRep.Unsigned.word
98 :     val ml_sshort : sshort -> MLRep.Signed.int
99 :     val ml_ushort : ushort -> MLRep.Unsigned.word
100 :     val ml_slong : slong -> MLRep.Signed.int
101 :     val ml_ulong : ulong -> MLRep.Unsigned.word
102 :     val ml_float : float -> MLRep.Real.real
103 :     val ml_double : double -> MLRep.Real.real
104 : blume 828 end
105 :    
106 :     (* type-abbreviations for a bit more convenience. *)
107 : blume 837 type 'c schar_obj = (schar, 'c) obj
108 :     type 'c uchar_obj = (uchar, 'c) obj
109 :     type 'c sint_obj = (sint, 'c) obj
110 :     type 'c uint_obj = (uint, 'c) obj
111 :     type 'c sshort_obj = (sshort, 'c) obj
112 :     type 'c ushort_obj = (ushort, 'c) obj
113 :     type 'c slong_obj = (slong, 'c) obj
114 :     type 'c ulong_obj = (ulong, 'c) obj
115 :     type 'c float_obj = (float, 'c) obj
116 :     type 'c double_obj = (double, 'c) obj
117 :     type 'c voidptr_obj = (voidptr, 'c) obj
118 :     type ('f, 'c) fptr_obj = ('f fptr, 'c) obj
119 :     type ('s, 'c) su_obj = ('s su, 'c) obj
120 : blume 828
121 :     (* alt *)
122 : blume 837 type 'c schar_obj' = (schar, 'c) obj'
123 :     type 'c uchar_obj' = (uchar, 'c) obj'
124 :     type 'c sint_obj' = (sint, 'c) obj'
125 :     type 'c uint_obj' = (uint, 'c) obj'
126 :     type 'c sshort_obj' = (sshort, 'c) obj'
127 :     type 'c ushort_obj' = (ushort, 'c) obj'
128 :     type 'c slong_obj' = (slong, 'c) obj'
129 :     type 'c ulong_obj' = (ulong, 'c) obj'
130 :     type 'c float_obj' = (float, 'c) obj'
131 :     type 'c double_obj' = (double, 'c) obj'
132 :     type 'c voidptr_obj' = (voidptr, 'c) obj'
133 :     type ('f, 'c) fptr_obj' = ('f fptr, 'c) obj'
134 :     type ('s, 'c) su_obj' = ('s su, 'c) obj'
135 : blume 828
136 :     (* bitfields aren't "ordinary objects", so they have their own type *)
137 : blume 1031 eqtype 'c sbf and 'c ubf
138 : blume 828
139 :     (*
140 :     * A family of types and corresponding values representing natural numbers.
141 :     * (An encoding in SML without using dependent types.)
142 :     *)
143 :     structure Dim : sig
144 :    
145 :     (* Internally, a value of type ('a, 'z) dim0 is just a number.
146 :     * The trick here is to give each of these numbers a different unique
147 :     * type. 'a will be a decimal encoding of the number's value in
148 :     * "type digits". 'z keeps track of whether the number is zero or not.
149 :     *)
150 :     type ('a, 'z) dim0
151 :    
152 :     (* We can always get the internal number back... *)
153 :     val toInt : ('a, 'z) dim0 -> int
154 :    
155 :     (* These two types act as "flags". They will be substituted for 'z
156 :     * and remember whether the value is zero or not. *)
157 :     type zero
158 :     type nonzero
159 :    
160 :     type 'a dim = ('a, nonzero) dim0
161 :    
162 :     (* These are the "type digits". Type "dec" acts as a "terminator".
163 :     * We chose its name so to remind us that the encoding is decimal.
164 :     * If a nonzero value's decimal representation is "<Dn>...<D0>", then
165 :     * its type will be "(dec dg<Dn> ... dg<D0>, nonzero) dim0", which
166 :     * is the same as "dec dg<Dn> ... dg<D0> dim". The type of the zero
167 :     * value is "(dec, zero) dim0". *)
168 :     type dec
169 : blume 840 type 'a dg0 and 'a dg1 and 'a dg2 and 'a dg3 and 'a dg4
170 :     type 'a dg5 and 'a dg6 and 'a dg7 and 'a dg8 and 'a dg9
171 : blume 828
172 :     (* Here are the corresponding constructors for ('a, 'z) dim0 values.
173 :     * The type for dg0 ensures that there will be no "leading zeros" in
174 :     * any encoding. This guarantees a 1-1 correspondence of constructable
175 :     * values and their types.
176 :     * To construct the value corresponding to a nonzero number whose
177 :     * decimal representation is "<Dn>...<D0>", one must invoke
178 :     * "dg<D0>' (... (dg<Dn>' dec')...)", i.e., the least significant
179 :     * digit appears leftmost. *)
180 :     val dec' : (dec, zero) dim0
181 :     val dg0' : 'a dim -> 'a dg0 dim
182 :     val dg1' : ('a, 'z) dim0 -> 'a dg1 dim
183 :     val dg2' : ('a, 'z) dim0 -> 'a dg2 dim
184 :     val dg3' : ('a, 'z) dim0 -> 'a dg3 dim
185 :     val dg4' : ('a, 'z) dim0 -> 'a dg4 dim
186 :     val dg5' : ('a, 'z) dim0 -> 'a dg5 dim
187 :     val dg6' : ('a, 'z) dim0 -> 'a dg6 dim
188 :     val dg7' : ('a, 'z) dim0 -> 'a dg7 dim
189 :     val dg8' : ('a, 'z) dim0 -> 'a dg8 dim
190 :     val dg9' : ('a, 'z) dim0 -> 'a dg9 dim
191 :    
192 :     (* Since having to reverse the sequence of digits seems unnatural,
193 :     * here is another set of constructors for dim values. These
194 :     * constructors use continuation-passing style and themselves
195 :     * have more complicated types. But their use is easier:
196 :     * To construct the value corresponding to a nonzero number whose
197 :     * decimal representation is "<Dn>...<D0>", one must invoke
198 :     * "dec dg<Dn> ... dg<D0> dim"; i.e., the least significant
199 :     * digit appears rightmost -- just like in the usual decimal
200 :     * notation for numbers that we are all familiar with.
201 :     * [Moreover, for any 'a dim value we have the neat property that
202 :     * it can be constructed by taking its type (expressed using "dim")
203 :     * and interpreting it as an expression. For example, the dim
204 :     * value representing 312 is "dec dg3 dg1 dg2 dim" and it can
205 :     * be constructed by evaluating "dec dg3 dg1 dg2 dim".] *)
206 :     val dec : ((dec, zero) dim0 -> 'b) -> 'b
207 :    
208 :     val dg0 : 'a dim -> ('a dg0 dim -> 'b) -> 'b
209 :     val dg1 : ('a, 'z) dim0 -> ('a dg1 dim -> 'b) -> 'b
210 :     val dg2 : ('a, 'z) dim0 -> ('a dg2 dim -> 'b) -> 'b
211 :     val dg3 : ('a, 'z) dim0 -> ('a dg3 dim -> 'b) -> 'b
212 :     val dg4 : ('a, 'z) dim0 -> ('a dg4 dim -> 'b) -> 'b
213 :     val dg5 : ('a, 'z) dim0 -> ('a dg5 dim -> 'b) -> 'b
214 :     val dg6 : ('a, 'z) dim0 -> ('a dg6 dim -> 'b) -> 'b
215 :     val dg7 : ('a, 'z) dim0 -> ('a dg7 dim -> 'b) -> 'b
216 :     val dg8 : ('a, 'z) dim0 -> ('a dg8 dim -> 'b) -> 'b
217 :     val dg9 : ('a, 'z) dim0 -> ('a dg9 dim -> 'b) -> 'b
218 :    
219 :     val dim : ('a, 'z) dim0 -> ('a, 'z) dim0
220 :     end
221 :    
222 :     (* sub-structure for dealing with run-time type info (sizes only) *)
223 :     structure S : sig
224 :    
225 :     (* Our size info itself is statically typed!
226 : blume 837 * The size info for a value stored in ('t, 'c) obj has
227 : blume 828 * the following type: *)
228 :     type 't size
229 :    
230 :     (* get a number out *)
231 :     val toWord : 't size -> word
232 :    
233 :     (* sizes for simple things *)
234 :     val schar : schar size
235 :     val uchar : uchar size
236 :     val sint : sint size
237 :     val uint : uint size
238 :     val sshort : sshort size
239 :     val ushort : ushort size
240 :     val slong : slong size
241 :     val ulong : ulong size
242 :     val float : float size
243 :     val double : double size
244 :    
245 :     val voidptr : voidptr size
246 : blume 1078 val ptr : 'o ptr size
247 : blume 828 val fptr : 'f fptr size
248 :     end
249 :    
250 :     (* sub-structure for dealing with run-time type info *)
251 :     structure T : sig
252 :    
253 : blume 975 (* Our RTTI itself is statically typed!
254 :     * The RTTI for a value stored in ('t, 'c) obj has
255 : blume 828 * the following type: *)
256 : blume 837 type 't typ
257 : blume 828
258 : blume 975 (* get the RTTI from an actual object *)
259 : blume 837 val typeof : ('t, 'c) obj -> 't typ
260 : blume 828
261 : blume 975 (* constructing new RTTI from existing RTTI *)
262 : blume 1078 val pointer : 't typ -> ('t, rw) obj ptr typ
263 :     val target : ('t, 'c) obj ptr typ -> 't typ
264 : blume 837 val arr : 't typ * 'n Dim.dim -> ('t, 'n) arr typ
265 :     val elem : ('t, 'n) arr typ -> 't typ
266 : blume 1078 val ro : ('t, 'c) obj ptr typ -> ('t, ro) obj ptr typ
267 : blume 828
268 : blume 975 (* calculating the size of an object given its RTTI *)
269 : blume 837 val sizeof : 't typ -> 't S.size
270 : blume 828
271 :     (* dimension of array type *)
272 : blume 837 val dim : ('t, 'n) arr typ -> 'n Dim.dim
273 : blume 828
274 : blume 975 (* RTTI for simple things *)
275 : blume 837 val schar : schar typ
276 :     val uchar : uchar typ
277 :     val sint : sint typ
278 :     val uint : uint typ
279 :     val sshort : sshort typ
280 :     val ushort : ushort typ
281 :     val slong : slong typ
282 :     val ulong : ulong typ
283 :     val float : float typ
284 :     val double : double typ
285 : blume 828
286 : blume 837 val voidptr : voidptr typ
287 : blume 828 end
288 :    
289 :     (* convert from regular (heavy) to alternative (light) versions *)
290 :     structure Light : sig
291 : blume 837 val obj : ('t, 'c) obj -> ('t, 'c) obj'
292 : blume 1078 val ptr : 'o ptr -> 'o ptr'
293 : blume 828 val fptr : 'f fptr -> 'f fptr'
294 :     end
295 :    
296 :     (* and vice versa *)
297 :     structure Heavy : sig
298 : blume 837 val obj : 't T.typ -> ('t, 'c) obj' -> ('t, 'c) obj
299 : blume 1078 val ptr : 'o ptr T.typ -> 'o ptr' -> 'o ptr
300 : blume 837 val fptr : 'f fptr T.typ -> 'f fptr' -> 'f fptr
301 : blume 828 end
302 :    
303 : blume 837 (* calculate size of an object *)
304 :     val sizeof : ('t, 'c) obj -> 't S.size
305 : blume 828
306 :     (* "fetch" methods for various types;
307 :     * fetching does not care about constness *)
308 :     structure Get : sig
309 :    
310 : blume 1036 (* primitive types; the results are concrete here *)
311 :     val schar : 'c schar_obj -> MLRep.Signed.int
312 :     val uchar : 'c uchar_obj -> MLRep.Unsigned.word
313 :     val sint : 'c sint_obj -> MLRep.Signed.int
314 :     val uint : 'c uint_obj -> MLRep.Unsigned.word
315 :     val sshort : 'c sshort_obj -> MLRep.Signed.int
316 :     val ushort : 'c ushort_obj -> MLRep.Unsigned.word
317 :     val slong : 'c slong_obj -> MLRep.Signed.int
318 :     val ulong : 'c ulong_obj -> MLRep.Unsigned.word
319 :     val float : 'c float_obj -> MLRep.Real.real
320 :     val double : 'c double_obj -> MLRep.Real.real
321 : blume 828
322 :     (* alt *)
323 : blume 1036 val schar' : 'c schar_obj' -> MLRep.Signed.int
324 :     val uchar' : 'c uchar_obj' -> MLRep.Unsigned.word
325 :     val sint' : 'c sint_obj' -> MLRep.Signed.int
326 :     val uint' : 'c uint_obj' -> MLRep.Unsigned.word
327 :     val sshort' : 'c sshort_obj' -> MLRep.Signed.int
328 :     val ushort' : 'c ushort_obj' -> MLRep.Unsigned.word
329 :     val slong' : 'c slong_obj' -> MLRep.Signed.int
330 :     val ulong' : 'c ulong_obj' -> MLRep.Unsigned.word
331 :     val float' : 'c float_obj' -> MLRep.Real.real
332 :     val double' : 'c double_obj' -> MLRep.Real.real
333 : blume 828
334 : blume 1036 (* fetching pointers; results have to be abstract *)
335 : blume 1078 val ptr : ('o ptr, 'c) obj -> 'o ptr
336 : blume 828 val fptr : ('f, 'c) fptr_obj -> 'f fptr
337 :     val voidptr : 'c voidptr_obj -> voidptr
338 :    
339 :     (* alt *)
340 : blume 1078 val ptr' : ('o ptr, 'c) obj' -> 'o ptr'
341 : blume 828 val fptr' : ('f, 'c) fptr_obj' -> 'f fptr'
342 :     val voidptr' : 'c voidptr_obj' -> voidptr
343 :    
344 : blume 1036 (* bitfields; concrete again *)
345 :     val sbf : 'c sbf -> MLRep.Signed.int
346 :     val ubf : 'c ubf -> MLRep.Unsigned.word
347 : blume 828 end
348 :    
349 :     (* "store" methods; these require rw objects *)
350 :     structure Set : sig
351 : blume 1036 (* primitive types; use concrete values *)
352 :     val schar : rw schar_obj * MLRep.Signed.int -> unit
353 :     val uchar : rw uchar_obj * MLRep.Unsigned.word -> unit
354 :     val sint : rw sint_obj * MLRep.Signed.int -> unit
355 :     val uint : rw uint_obj * MLRep.Unsigned.word -> unit
356 :     val sshort : rw sshort_obj * MLRep.Signed.int -> unit
357 :     val ushort : rw ushort_obj * MLRep.Unsigned.word -> unit
358 :     val slong : rw slong_obj * MLRep.Signed.int -> unit
359 :     val ulong : rw ulong_obj * MLRep.Unsigned.word -> unit
360 :     val float : rw float_obj * MLRep.Real.real -> unit
361 :     val double : rw double_obj * MLRep.Real.real -> unit
362 : blume 828
363 :     (* alt *)
364 : blume 1036 val schar' : rw schar_obj' * MLRep.Signed.int -> unit
365 :     val uchar' : rw uchar_obj' * MLRep.Unsigned.word -> unit
366 :     val sint' : rw sint_obj' * MLRep.Signed.int -> unit
367 :     val uint' : rw uint_obj' * MLRep.Unsigned.word -> unit
368 :     val sshort' : rw sshort_obj' * MLRep.Signed.int -> unit
369 :     val ushort' : rw ushort_obj' * MLRep.Unsigned.word -> unit
370 :     val slong' : rw slong_obj' * MLRep.Signed.int -> unit
371 :     val ulong' : rw ulong_obj' * MLRep.Unsigned.word -> unit
372 :     val float' : rw float_obj' * MLRep.Real.real -> unit
373 :     val double' : rw double_obj' * MLRep.Real.real -> unit
374 : blume 828
375 : blume 1036 (* storing pointers; abstract *)
376 : blume 1078 val ptr : ('o ptr, rw) obj * 'o ptr -> unit
377 : blume 828 val fptr : ('f, rw) fptr_obj * 'f fptr -> unit
378 :     val voidptr : rw voidptr_obj * voidptr -> unit
379 :    
380 :     (* alt *)
381 : blume 1078 val ptr' : ('o ptr, rw) obj' * 'o ptr' -> unit
382 : blume 828 val fptr' : ('f, rw) fptr_obj' * 'f fptr' -> unit
383 :     val voidptr' : rw voidptr_obj' * voidptr -> unit
384 :    
385 :     (* When storing, voidptr is compatible with any ptr type
386 : blume 975 * (just like in C). This should eliminate most need for RTTI in
387 : blume 828 * practice. *)
388 : blume 1078 val ptr_voidptr : ('o ptr, rw) obj * voidptr -> unit
389 : blume 828
390 :     (* alt *)
391 : blume 1078 val ptr_voidptr' : ('o ptr, rw) obj' * voidptr -> unit
392 : blume 828
393 : blume 1036 (* bitfields; concrete *)
394 :     val sbf : rw sbf * MLRep.Signed.int -> unit
395 :     val ubf : rw ubf * MLRep.Unsigned.word -> unit
396 : blume 828 end
397 :    
398 :     (* copying the contents of arbitrary objects *)
399 : blume 837 val copy : { from: ('t, 'c) obj, to: ('t, rw) obj } -> unit
400 : blume 828
401 :     (* alt *)
402 : blume 837 val copy' : 't S.size -> { from: ('t, 'c) obj', to: ('t, rw) obj' } -> unit
403 : blume 828
404 : blume 1021 (* manipulating object constness
405 :     * rw -> ro: this direction just accounts for the fact that
406 :     * rw is conceptually a subtype of ro
407 :     * ro -> rw: this is not safe, but C makes it so easy that we
408 :     * might as well directly support it;
409 :     * Concretely, we make both operations polymorphic in the argument
410 :     * constness. Moreover, the second (unsafe) direction is also
411 :     * polymorphic in the result. This can be used to effectively
412 :     * implement a conversion to "whatever the context wants":
413 :     *)
414 :     val ro : ('t, 'c) obj -> ('t, ro) obj
415 :     val rw : ('t, 'sc) obj -> ('t, 'tc) obj
416 :    
417 :     (* alt *)
418 :     val ro' : ('t, 'c) obj' -> ('t, ro) obj'
419 :     val rw' : ('t, 'sc) obj' -> ('t, 'tc) obj'
420 :    
421 : blume 828 (* operations on (mostly) pointers *)
422 :     structure Ptr : sig
423 :    
424 :     (* going from object to pointer and vice versa *)
425 : blume 1078 val |&| : ('t, 'c) obj -> ('t, 'c) obj ptr
426 :     val |*| : ('t, 'c) obj ptr -> ('t, 'c) obj
427 : blume 828
428 :     (* alt *)
429 : blume 1078 val |&! : ('t, 'c) obj' -> ('t, 'c) obj ptr'
430 :     val |*! : ('t, 'c) obj ptr' -> ('t, 'c) obj'
431 : blume 828
432 :     (* comparing pointers *)
433 : blume 1078 val compare : 'o ptr * 'o ptr -> order
434 : blume 828
435 :     (* alt *)
436 : blume 1078 val compare' : 'o ptr' * 'o ptr' -> order
437 : blume 828
438 :     (* going from pointer to void*; this also accounts for a conceptual
439 :     * subtyping relation and is safe *)
440 : blume 1078 val inject : 'o ptr -> voidptr
441 : blume 828
442 :     (* alt *)
443 : blume 1078 val inject' : 'o ptr' -> voidptr
444 : blume 828
445 :     (* the opposite is not safe, but C makes it not only easy but also
446 : blume 975 * almost necessary; we use our RTTI interface to specify the pointer
447 : blume 828 * type (not the element type!) *)
448 : blume 1078 val cast : 'o ptr T.typ -> voidptr -> 'o ptr
449 : blume 828
450 :     (* alt *)
451 : blume 1078 val cast' : 'o ptr T.typ -> voidptr -> 'o ptr'
452 : blume 828
453 :     (* NULL as void* *)
454 :     val vNull : voidptr
455 :    
456 :     (* projecting vNull to given pointer type *)
457 : blume 1078 val null : 'o ptr T.typ -> 'o ptr
458 : blume 828
459 :     (* the "light" NULL pointer is simply a polymorphic constant *)
460 : blume 1078 val null' : 'o ptr'
461 : blume 828
462 : blume 1031 (* fptr version of NULL *)
463 :     val fnull : 'f fptr T.typ -> 'f fptr
464 :    
465 :     (* again, "light" version is simply a polymorphic constant *)
466 :     val fnull' : 'f fptr'
467 :    
468 : blume 828 (* checking for NULL pointer *)
469 :     val vIsNull : voidptr -> bool
470 :    
471 :     (* combining inject and vIsNull for convenience *)
472 : blume 1078 val isNull : 'o ptr -> bool
473 : blume 828
474 :     (* alt *)
475 : blume 1078 val isNull' : 'o ptr' -> bool
476 : blume 828
477 : blume 1031 (* checking a function pointer for NULL *)
478 :     val isFNull : 'f fptr -> bool
479 :    
480 :     (* alt *)
481 :     val isFNull' : 'f fptr' -> bool
482 :    
483 : blume 828 (* pointer arithmetic *)
484 : blume 1078 val |+| : ('t, 'c) obj ptr * int -> ('t, 'c) obj ptr
485 :     val |-| : ('t, 'c) obj ptr * ('t, 'c) obj ptr -> int
486 : blume 828
487 :     (* alt; needs explicit size (for element) *)
488 : blume 1078 val |+! : 't S.size -> ('t, 'c) obj ptr' * int -> ('t, 'c) obj ptr'
489 :     val |-! : 't S.size -> ('t, 'c) obj ptr' * ('t, 'c) obj ptr' -> int
490 : blume 828
491 :     (* subscript through a pointer; this is unchecked *)
492 : blume 1078 val sub : ('t, 'c) obj ptr * int -> ('t, 'c) obj
493 : blume 828
494 :     (* alt; needs explicit size (for element) *)
495 : blume 1078 val sub' : 't S.size -> ('t, 'c) obj ptr' * int -> ('t, 'c) obj'
496 : blume 1021
497 :     (* constness manipulation for pointers *)
498 : blume 1078 val ro : ('t, 'c) obj ptr -> ('t, ro) obj ptr
499 :     val rw : ('t, 'sc) obj ptr -> ('t, 'tc) obj ptr
500 :     val ro' : ('t, 'c) obj ptr' -> ('t, ro) obj ptr'
501 :     val rw' : ('t, 'sc) obj ptr' -> ('t, 'tc) obj ptr'
502 : blume 828 end
503 :    
504 :     (* operations on (mostly) arrays *)
505 :     structure Arr : sig
506 :    
507 :     (* array subscript;
508 : blume 975 * since we have RTTI, we can actually make this safe: we raise
509 : blume 828 * General.Subscript for out-of-bounds access;
510 :     * for unchecked access, go through arr_decay and ptr_sub *)
511 : blume 837 val sub : (('t, 'n) arr, 'c) obj * int -> ('t, 'c) obj
512 : blume 828
513 :     (* alt; needs explicit type (for array) *)
514 : blume 837 val sub' : ('t, 'n) arr T.typ ->
515 :     (('t, 'n) arr, 'c) obj' * int -> ('t, 'c) obj'
516 : blume 828
517 :     (* let an array object decay, yielding pointer to first element *)
518 : blume 1078 val decay : (('t, 'n) arr, 'c) obj -> ('t, 'c) obj ptr
519 : blume 828
520 :     (* alt *)
521 : blume 1078 val decay' : (('t, 'n) arr, 'c) obj' -> ('t, 'c) obj ptr'
522 : blume 828
523 :     (* reconstruct an array object from the pointer to its first element *)
524 : blume 1078 val reconstruct :
525 :     ('t, 'c) obj ptr * 'n Dim.dim -> (('t, 'n) arr, 'c) obj
526 : blume 828
527 :     (* alt *)
528 : blume 1078 val reconstruct':
529 :     ('t, 'c) obj ptr' * 'n Dim.dim -> (('t, 'n) arr, 'c) obj'
530 : blume 828
531 :     (* dimension of array object *)
532 : blume 837 val dim : (('t, 'n) arr, 'c) obj -> 'n Dim.dim
533 : blume 828 end
534 :    
535 :     (* allocating new objects *)
536 : blume 1021 val new : 't T.typ -> ('t, 'c) obj
537 : blume 828
538 :     (* alt *)
539 : blume 1021 val new' : 't S.size -> ('t, 'c) obj'
540 : blume 828
541 :     (* freeing objects that were allocated earlier *)
542 : blume 837 val discard : ('t, 'c) obj -> unit
543 : blume 828
544 :     (* alt *)
545 : blume 837 val discard' : ('t, 'c) obj' -> unit
546 : blume 828
547 :     (* allocating a dynamically-sized array *)
548 : blume 1078 val alloc : 't T.typ -> word -> ('t, 'c) obj ptr
549 : blume 828
550 :     (* alt *)
551 : blume 1078 val alloc' : 't S.size -> word -> ('t, 'c) obj ptr'
552 : blume 828
553 :     (* freeing through pointers *)
554 : blume 1078 val free : 'o ptr -> unit
555 : blume 828
556 :     (* alt *)
557 : blume 1078 val free' : 'o ptr' -> unit
558 : blume 828
559 :     (* perform function call through function-pointer *)
560 :     val call : ('a -> 'b) fptr * 'a -> 'b
561 :    
562 :     (* alt; needs explicit type for the function pointer *)
563 : blume 837 val call' : ('a -> 'b) fptr T.typ -> ('a -> 'b) fptr' * 'a -> 'b
564 : blume 1015
565 :     (* completely unsafe stuff that every C programmer just *loves* to do *)
566 :     structure U : sig
567 :     val fcast : 'a fptr' -> 'b fptr'
568 : blume 1078 val p2i : 'o ptr' -> ulong
569 :     val i2p : ulong -> 'o ptr'
570 : blume 1015 end
571 : blume 828 end

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0