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/releases/release-110.37/src/ml-nlffi-lib/c.sig
ViewVC logotype

Annotation of /sml/releases/release-110.37/src/ml-nlffi-lib/c.sig

Parent Directory Parent Directory | Revision Log Revision Log


Revision 836 - (view) (download) (as text)
Original Path: sml/trunk/src/ml-nlffi-lib/c.sig

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 :     (* objects of type 't, constness 'c;
11 :     * The type 'f is an artifact of how function pointers are handled:
12 :     * - 'f is the 'f in 'f fptr for any type derived (via ptr or arr)
13 :     * from 'f fptr.
14 :     * - For all other types, 'f is unit.
15 :     * The 't type variable will be instantiated with the object's "witness"
16 :     * type. The intention is that there be an isomorphism between such
17 :     * witness types and corresponding C types.
18 :     *
19 :     * Witness types are often the same as the (abstract) type of the value
20 :     * stored in the object. However, this is merely a coincidence. For
21 :     * example, a constant object holding a pointer to a read-write integer
22 :     * would have type ((sint, unit, rw) ptr, unit, ro) obj and the value
23 :     * itself has type (sint, unit, rw) ptr.
24 :     * However, in the case of the "light" version of this object (see below),
25 :     * the object type is ((sint, unit, rw) ptr, unit, ro) obj' while fetching
26 :     * from this object gives a value of type (sint, unit, rw) ptr'.
27 :     * (In other words, we use the "heavy" versions of value types as witness
28 :     * types -- even in the "light" case.) *)
29 :     type ('t, 'f, 'c) obj
30 :    
31 :     (* an alternative "light-weight" version that does not carry RTI at
32 :     * the cost of requiring explicit passing of RTI for certain operations *)
33 :     type ('t, 'f, 'c) obj'
34 :    
35 :     (* constness property, to be substituted for 'c *)
36 :     type ro
37 :     type rw
38 :    
39 :     (* things to be substituted for 't *)
40 :     type ('t, 'f, 'c) ptr (* pointer to ('t, 'f, 'c) obj *)
41 : blume 836 type ('t, 'n) arr (* 'n-sized array with 't elements *)
42 : blume 828
43 :     (* light-weight alternative *)
44 :     type ('t, 'f, 'c) ptr'
45 :    
46 :     (* void* and function pointers *)
47 :     type voidptr (* C's void* *)
48 :     type 'f fptr (* a function pointer *)
49 :    
50 :     (* alt *)
51 :     type 'f fptr'
52 :    
53 :     (* structures and unions *)
54 :     type 'tag su (* struct/union named 'tag;
55 :     * 'tag is drawn from the types
56 :     * defined in the Tag module *)
57 :    
58 :     (* primtypes (signed/unsigned char, int, short, long; float, double) *)
59 :     type schar
60 :     type uchar
61 :     type sint
62 :     type uint
63 :     type sshort
64 :     type ushort
65 :     type slong
66 :     type ulong
67 :     type float
68 :     type double
69 :    
70 :     (* going from abstract to concrete and vice versa *)
71 :     structure Cvt : sig
72 :     (* ML -> C *)
73 :     val c_schar : MLRep.SChar.int -> schar
74 :     val c_uchar : MLRep.UChar.word -> uchar
75 :     val c_sint : MLRep.SInt.int -> sint
76 :     val c_uint : MLRep.UInt.word -> uint
77 :     val c_sshort : MLRep.SShort.int -> sshort
78 :     val c_ushort : MLRep.UShort.word -> ushort
79 :     val c_slong : MLRep.SLong.int -> slong
80 :     val c_ulong : MLRep.ULong.word -> ulong
81 :     val c_float : MLRep.Float.real -> float
82 :     val c_double : MLRep.Double.real -> double
83 :    
84 :     (* C -> ML *)
85 :     val ml_schar : schar -> MLRep.SChar.int
86 :     val ml_uchar : uchar -> MLRep.UChar.word
87 :     val ml_sint : sint -> MLRep.SInt.int
88 :     val ml_uint : uint -> MLRep.UInt.word
89 :     val ml_sshort : sshort -> MLRep.SShort.int
90 :     val ml_ushort : ushort -> MLRep.UShort.word
91 :     val ml_slong : slong -> MLRep.SLong.int
92 :     val ml_ulong : ulong -> MLRep.ULong.word
93 :     val ml_float : float -> MLRep.Float.real
94 :     val ml_double : double -> MLRep.Double.real
95 :     end
96 :    
97 :     (* type-abbreviations for a bit more convenience. *)
98 :     type 'c schar_obj = (schar, unit, 'c) obj
99 :     type 'c uchar_obj = (uchar, unit, 'c) obj
100 :     type 'c sint_obj = (sint, unit, 'c) obj
101 :     type 'c uint_obj = (uint, unit, 'c) obj
102 :     type 'c sshort_obj = (sshort, unit, 'c) obj
103 :     type 'c ushort_obj = (ushort, unit, 'c) obj
104 :     type 'c slong_obj = (slong, unit, 'c) obj
105 :     type 'c ulong_obj = (ulong, unit, 'c) obj
106 :     type 'c float_obj = (float, unit, 'c) obj
107 :     type 'c double_obj = (double, unit, 'c) obj
108 :     type 'c voidptr_obj = (voidptr, unit, 'c) obj
109 :     type ('f, 'c) fptr_obj = ('f fptr, 'f, 'c) obj
110 :     type ('s, 'c) su_obj = ('s su, unit, 'c) obj
111 :    
112 :     (* alt *)
113 :     type 'c schar_obj' = (schar, unit, 'c) obj'
114 :     type 'c uchar_obj' = (uchar, unit, 'c) obj'
115 :     type 'c sint_obj' = (sint, unit, 'c) obj'
116 :     type 'c uint_obj' = (uint, unit, 'c) obj'
117 :     type 'c sshort_obj' = (sshort, unit, 'c) obj'
118 :     type 'c ushort_obj' = (ushort, unit, 'c) obj'
119 :     type 'c slong_obj' = (slong, unit, 'c) obj'
120 :     type 'c ulong_obj' = (ulong, unit, 'c) obj'
121 :     type 'c float_obj' = (float, unit, 'c) obj'
122 :     type 'c double_obj' = (double, unit, 'c) obj'
123 :     type 'c voidptr_obj' = (voidptr, unit, 'c) obj'
124 :     type ('f, 'c) fptr_obj' = ('f fptr, 'f, 'c) obj'
125 :     type ('s, 'c) su_obj' = ('s su, unit, 'c) obj'
126 :    
127 :     (* bitfields aren't "ordinary objects", so they have their own type *)
128 :     type 'c sbf
129 :     type 'c ubf
130 :    
131 :     (*
132 :     * A family of types and corresponding values representing natural numbers.
133 :     * (An encoding in SML without using dependent types.)
134 :     *)
135 :     structure Dim : sig
136 :    
137 :     (* Internally, a value of type ('a, 'z) dim0 is just a number.
138 :     * The trick here is to give each of these numbers a different unique
139 :     * type. 'a will be a decimal encoding of the number's value in
140 :     * "type digits". 'z keeps track of whether the number is zero or not.
141 :     *)
142 :     type ('a, 'z) dim0
143 :    
144 :     (* We can always get the internal number back... *)
145 :     val toInt : ('a, 'z) dim0 -> int
146 :    
147 :     (* These two types act as "flags". They will be substituted for 'z
148 :     * and remember whether the value is zero or not. *)
149 :     type zero
150 :     type nonzero
151 :    
152 :     type 'a dim = ('a, nonzero) dim0
153 :    
154 :     (* These are the "type digits". Type "dec" acts as a "terminator".
155 :     * We chose its name so to remind us that the encoding is decimal.
156 :     * If a nonzero value's decimal representation is "<Dn>...<D0>", then
157 :     * its type will be "(dec dg<Dn> ... dg<D0>, nonzero) dim0", which
158 :     * is the same as "dec dg<Dn> ... dg<D0> dim". The type of the zero
159 :     * value is "(dec, zero) dim0". *)
160 :     type dec
161 :     type 'a dg0
162 :     type 'a dg1
163 :     type 'a dg2
164 :     type 'a dg3
165 :     type 'a dg4
166 :     type 'a dg5
167 :     type 'a dg6
168 :     type 'a dg7
169 :     type 'a dg8
170 :     type 'a dg9
171 :    
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 :     * The size info for a value stored in ('t, 'f, 'c) obj has
227 :     * 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 :     val ptr : ('t, 'f, 'c) ptr size
247 :     val fptr : 'f fptr size
248 :     end
249 :    
250 :     (* sub-structure for dealing with run-time type info *)
251 :     structure T : sig
252 :    
253 :     (* Our RTI itself is statically typed!
254 :     * The RTI for a value stored in ('t, 'f, 'c) obj has
255 :     * the following type: *)
256 :     type ('t, 'f) typ
257 :    
258 :     (* again, a lot of abbreviations *)
259 :     type schar_typ = (schar, unit) typ
260 :     type uchar_typ = (uchar, unit) typ
261 :     type sint_typ = (sint, unit) typ
262 :     type uint_typ = (uint, unit) typ
263 :     type sshort_typ = (sshort, unit) typ
264 :     type ushort_typ = (ushort, unit) typ
265 :     type slong_typ = (slong, unit) typ
266 :     type ulong_typ = (ulong, unit) typ
267 :     type float_typ = (float, unit) typ
268 :     type double_typ = (double, unit) typ
269 :     type voidptr_typ = (voidptr, unit) typ
270 :     type 'f fptr_typ = ('f fptr, 'f) typ
271 :     type 's su_typ = ('s su, unit) typ
272 :    
273 :     (* get the RTI from an actual object *)
274 :     val typeof : ('t, 'f, 'c) obj -> ('t, 'f) typ
275 :    
276 :     (* constructing new RTI from existing RTI *)
277 :     val pointer : ('t, 'f) typ -> (('t, 'f, rw) ptr, 'f) typ
278 :     val target : (('t, 'f, 'c) ptr, 'f) typ -> ('t, 'f) typ
279 : blume 836 val arr : ('t, 'f) typ * 'n Dim.dim -> (('t, 'n) arr, 'f) typ
280 :     val elem : (('t, 'n) arr, 'f) typ -> ('t, 'f) typ
281 : blume 828 val ro : (('t, 'f, 'c) ptr, 'f) typ -> (('t, 'f, ro) ptr, 'f) typ
282 :    
283 :     (* calculating the size of an object given its RTI *)
284 :     val sizeof : ('t, 'f) typ -> 't S.size
285 :    
286 :     (* dimension of array type *)
287 : blume 836 val dim : (('t, 'n) arr, 'f) typ -> 'n Dim.dim
288 : blume 828
289 :     (* RTI for simple things *)
290 :     val schar : schar_typ
291 :     val uchar : uchar_typ
292 :     val sint : sint_typ
293 :     val uint : uint_typ
294 :     val sshort : sshort_typ
295 :     val ushort : ushort_typ
296 :     val slong : slong_typ
297 :     val ulong : ulong_typ
298 :     val float : float_typ
299 :     val double : double_typ
300 :    
301 :     val voidptr : voidptr_typ
302 :     end
303 :    
304 :     (* convert from regular (heavy) to alternative (light) versions *)
305 :     structure Light : sig
306 :     val obj : ('t, 'f, 'c) obj -> ('t, 'f, 'c) obj'
307 :     val ptr : ('t, 'f, 'c) ptr -> ('t, 'f, 'c) ptr'
308 :     val fptr : 'f fptr -> 'f fptr'
309 :     end
310 :    
311 :     (* and vice versa *)
312 :     structure Heavy : sig
313 :     val obj : ('t, 'f) T.typ -> ('t, 'f, 'c) obj' -> ('t, 'f, 'c) obj
314 :     val ptr : ('t, 'f) T.typ -> ('t, 'f, 'c) ptr' -> ('t, 'f, 'c) ptr
315 :     val fptr : 'f T.fptr_typ -> 'f fptr' -> 'f fptr
316 :     end
317 :    
318 :     (* calculate size of an object in bytes *)
319 :     val sizeof : ('t, 'f, 'c) obj -> 't S.size
320 :    
321 :     (* "fetch" methods for various types;
322 :     * fetching does not care about constness *)
323 :     structure Get : sig
324 :    
325 :     (* primitive types *)
326 :     val schar : 'c schar_obj -> schar
327 :     val uchar : 'c uchar_obj -> uchar
328 :     val sint : 'c sint_obj -> sint
329 :     val uint : 'c uint_obj -> uint
330 :     val sshort : 'c sshort_obj -> sshort
331 :     val ushort : 'c ushort_obj -> ushort
332 :     val slong : 'c slong_obj -> slong
333 :     val ulong : 'c ulong_obj -> ulong
334 :     val float : 'c float_obj -> float
335 :     val double : 'c double_obj -> double
336 :    
337 :     (* alt *)
338 :     val schar' : 'c schar_obj' -> schar
339 :     val uchar' : 'c uchar_obj' -> uchar
340 :     val sint' : 'c sint_obj' -> sint
341 :     val uint' : 'c uint_obj' -> uint
342 :     val sshort' : 'c sshort_obj' -> sshort
343 :     val ushort' : 'c ushort_obj' -> ushort
344 :     val slong' : 'c slong_obj' -> slong
345 :     val ulong' : 'c ulong_obj' -> ulong
346 :     val float' : 'c float_obj' -> float
347 :     val double' : 'c double_obj' -> double
348 :    
349 :     (* fetching pointers *)
350 :     val ptr : (('t, 'f, 'pc) ptr, 'f, 'c) obj -> ('t, 'f, 'pc) ptr
351 :     val fptr : ('f, 'c) fptr_obj -> 'f fptr
352 :     val voidptr : 'c voidptr_obj -> voidptr
353 :    
354 :     (* alt *)
355 :     val ptr' : (('t, 'f, 'pc) ptr, 'f, 'c) obj' -> ('t, 'f, 'pc) ptr'
356 :     val fptr' : ('f, 'c) fptr_obj' -> 'f fptr'
357 :     val voidptr' : 'c voidptr_obj' -> voidptr
358 :    
359 :     (* bitfields *)
360 :     val sbf : 'c sbf -> sint
361 :     val ubf : 'c ubf -> uint
362 :     end
363 :    
364 :     (* "store" methods; these require rw objects *)
365 :     structure Set : sig
366 :     (* primitive types *)
367 :     val schar : rw schar_obj * schar -> unit
368 :     val uchar : rw uchar_obj * uchar -> unit
369 :     val sint : rw sint_obj * sint -> unit
370 :     val uint : rw uint_obj * uint -> unit
371 :     val sshort : rw sshort_obj * sshort -> unit
372 :     val ushort : rw ushort_obj * ushort -> unit
373 :     val slong : rw slong_obj * slong -> unit
374 :     val ulong : rw ulong_obj * ulong -> unit
375 :     val float : rw float_obj * float -> unit
376 :     val double : rw double_obj * double -> unit
377 :    
378 :     (* alt *)
379 :     val schar' : rw schar_obj' * schar -> unit
380 :     val uchar' : rw uchar_obj' * uchar -> unit
381 :     val sint' : rw sint_obj' * sint -> unit
382 :     val uint' : rw uint_obj' * uint -> unit
383 :     val sshort' : rw sshort_obj' * sshort -> unit
384 :     val ushort' : rw ushort_obj' * ushort -> unit
385 :     val slong' : rw slong_obj' * slong -> unit
386 :     val ulong' : rw ulong_obj' * ulong -> unit
387 :     val float' : rw float_obj' * float -> unit
388 :     val double' : rw double_obj' * double -> unit
389 :    
390 :     (* storing pointers *)
391 :     val ptr : (('t, 'f, 'pc) ptr, 'f, rw) obj * ('t, 'f, 'pc) ptr -> unit
392 :     val fptr : ('f, rw) fptr_obj * 'f fptr -> unit
393 :     val voidptr : rw voidptr_obj * voidptr -> unit
394 :    
395 :     (* alt *)
396 :     val ptr' : (('t, 'f, 'pc) ptr, 'f, rw) obj' * ('t, 'f, 'pc) ptr' -> unit
397 :     val fptr' : ('f, rw) fptr_obj' * 'f fptr' -> unit
398 :     val voidptr' : rw voidptr_obj' * voidptr -> unit
399 :    
400 :     (* When storing, voidptr is compatible with any ptr type
401 :     * (just like in C). This should eliminate most need for RTI in
402 :     * practice. *)
403 :     val ptr_voidptr : (('t, 'f, 'pc) ptr, 'f, rw) obj * voidptr -> unit
404 :    
405 :     (* alt *)
406 :     val ptr_voidptr' : (('t, 'f, 'pc) ptr, 'f, rw) obj' * voidptr -> unit
407 :    
408 :     (* bitfields *)
409 :     val sbf : rw sbf * sint -> unit
410 :     val ubf : rw ubf * uint -> unit
411 :     end
412 :    
413 :     (* copying the contents of arbitrary objects *)
414 :     val copy : { from: ('t, 'f, 'c) obj, to: ('t, 'f, rw) obj } -> unit
415 :    
416 :     (* alt *)
417 :     val copy' : 't S.size ->
418 :     { from: ('t, 'f, 'c) obj', to: ('t, 'f, rw) obj' } -> unit
419 :    
420 :     (* operations on (mostly) pointers *)
421 :     structure Ptr : sig
422 :    
423 :     (* going from object to pointer and vice versa *)
424 :     val |&| : ('t, 'f, 'c) obj -> ('t, 'f, 'c) ptr
425 :     val |*| : ('t, 'f, 'c) ptr -> ('t, 'f, 'c) obj
426 :    
427 :     (* alt *)
428 :     val |&! : ('t, 'f, 'c) obj' -> ('t, 'f, 'c) ptr'
429 :     val |*! : ('t, 'f, 'c) ptr' -> ('t, 'f, 'c) obj'
430 :    
431 :     (* comparing pointers *)
432 :     val compare : ('t, 'f, 'c) ptr * ('t, 'f, 'c) ptr -> order
433 :    
434 :     (* alt *)
435 :     val compare' : ('t, 'f, 'c) ptr' * ('t, 'f, 'c) ptr' -> order
436 :    
437 :     (* going from pointer to void*; this also accounts for a conceptual
438 :     * subtyping relation and is safe *)
439 :     val inject : ('t, 'f, 'c) ptr -> voidptr
440 :    
441 :     (* alt *)
442 :     val inject' : ('t, 'f, 'c) ptr' -> voidptr
443 :    
444 :     (* the opposite is not safe, but C makes it not only easy but also
445 :     * almost necessary; we use our RTI interface to specify the pointer
446 :     * type (not the element type!) *)
447 :     val project : (('t, 'f, 'c) ptr, 'f) T.typ ->
448 :     voidptr -> ('t, 'f, 'c) ptr
449 :    
450 :     (* alt *)
451 :     val project' : (('t, 'f, 'c) ptr, 'f) T.typ ->
452 :     voidptr -> ('t, 'f, 'c) ptr'
453 :    
454 :     (* NULL as void* *)
455 :     val vNull : voidptr
456 :    
457 :     (* projecting vNull to given pointer type *)
458 :     val null : (('t, 'f, 'c) ptr, 'f) T.typ -> ('t, 'f, 'c) ptr
459 :    
460 :     (* the "light" NULL pointer is simply a polymorphic constant *)
461 :     val null' : ('t, 'f, 'c) ptr'
462 :    
463 :     (* checking for NULL pointer *)
464 :     val vIsNull : voidptr -> bool
465 :    
466 :     (* combining inject and vIsNull for convenience *)
467 :     val isNull : ('t, 'f, 'c) ptr -> bool
468 :    
469 :     (* alt *)
470 :     val isNull' : ('t, 'f, 'c) ptr' -> bool
471 :    
472 :     (* pointer arithmetic *)
473 :     val |+| : ('t, 'f, 'c) ptr * int -> ('t, 'f, 'c) ptr
474 :     val |-| : ('t, 'f, 'c) ptr * ('t, 'f, 'c) ptr -> int
475 :    
476 :     (* alt; needs explicit size (for element) *)
477 :     val |+! : 't S.size -> ('t, 'f, 'c) ptr' * int -> ('t, 'f, 'c) ptr'
478 :     val |-! : 't S.size -> ('t, 'f, 'c) ptr' * ('t, 'f, 'c) ptr' -> int
479 :    
480 :     (* subscript through a pointer; this is unchecked *)
481 :     val sub : ('t, 'f, 'c) ptr * int -> ('t, 'f, 'c) obj
482 :    
483 :     (* alt; needs explicit size (for element) *)
484 :     val sub' : 't S.size -> ('t, 'f, 'c) ptr' * int -> ('t, 'f, 'c) obj'
485 :     end
486 :    
487 :     (* manipulating object constness
488 :     * rw -> ro: this direction just accounts for the fact that
489 :     * rw is conceptually a subtype of ro
490 :     * ro -> rw: this is not safe, but C makes it so easy that we
491 :     * might as well directly support it *)
492 :     val ro : ('t, 'f, 'c) obj -> ('t, 'f, ro) obj
493 :     val rw : ('t, 'f, 'c) obj -> ('t, 'f, rw) obj
494 :    
495 :     (* alt *)
496 :     val ro' : ('t, 'f, 'c) obj' -> ('t, 'f, ro) obj'
497 :     val rw' : ('t, 'f, 'c) obj' -> ('t, 'f, rw) obj'
498 :    
499 :     (* operations on (mostly) arrays *)
500 :     structure Arr : sig
501 :    
502 :     (* array subscript;
503 :     * since we have RTI, we can actually make this safe: we raise
504 :     * General.Subscript for out-of-bounds access;
505 :     * for unchecked access, go through arr_decay and ptr_sub *)
506 : blume 836 val sub : (('t, 'n) arr, 'f, 'c) obj * int -> ('t, 'f, 'c) obj
507 : blume 828
508 :     (* alt; needs explicit type (for array) *)
509 : blume 836 val sub' : (('t, 'n) arr, 'f) T.typ ->
510 :     (('t, 'n) arr, 'f, 'c) obj' * int -> ('t, 'f, 'c) obj'
511 : blume 828
512 :     (* let an array object decay, yielding pointer to first element *)
513 : blume 836 val decay : (('t, 'n) arr, 'f, 'c) obj -> ('t, 'f, 'c) ptr
514 : blume 828
515 :     (* alt *)
516 : blume 836 val decay' : (('t, 'n) arr, 'f, 'c) obj' -> ('t, 'f, 'c) ptr'
517 : blume 828
518 :     (* reconstruct an array object from the pointer to its first element *)
519 :     val reconstruct :
520 : blume 836 ('t, 'f, 'c) ptr * 'n Dim.dim -> (('t, 'n) arr, 'f, 'c) obj
521 : blume 828
522 :     (* alt *)
523 :     val reconstruct' :
524 : blume 836 ('t, 'f, 'c) ptr' * 'n Dim.dim -> (('t, 'n) arr, 'f, 'c) obj'
525 : blume 828
526 :     (* dimension of array object *)
527 : blume 836 val dim : (('t, 'n) arr, 'f, 'c) obj -> 'n Dim.dim
528 : blume 828 end
529 :    
530 :     (* allocating new objects *)
531 :     val new : ('t, 'f) T.typ -> ('t, 'f, rw) obj option
532 :    
533 :     (* alt *)
534 :     val new' : ('t, 'f) T.typ -> ('t, 'f, rw) obj' option
535 :    
536 :     (* allocating something that does not involve function pointers... *)
537 :     val new'' : 't S.size -> ('t, unit, rw) obj' option
538 :    
539 :     (* freeing objects that were allocated earlier *)
540 :     val discard : ('t, 'f, 'c) obj -> unit
541 :    
542 :     (* alt *)
543 :     val discard' : ('t, 'f, 'c) obj' -> unit
544 :    
545 :     (* allocating a dynamically-sized array *)
546 :     val alloc : ('t, 'f) T.typ -> word -> ('t, 'f, rw) ptr option
547 :    
548 :     (* alt *)
549 :     val alloc' : ('t, 'f) T.typ -> word -> ('t, 'f, rw) ptr' option
550 :    
551 :     (* alt, without function pointers *)
552 :     val alloc'' : 't S.size -> word -> ('t, unit, rw) ptr' option
553 :    
554 :     (* freeing through pointers *)
555 :     val free : ('t, 'f, 'c) ptr -> unit
556 :    
557 :     (* alt *)
558 :     val free' : ('t, 'f, 'c) ptr' -> unit
559 :    
560 :     (* perform function call through function-pointer *)
561 :     val call : ('a -> 'b) fptr * 'a -> 'b
562 :    
563 :     (* alt; needs explicit type for the function pointer *)
564 :     val call' : (('a -> 'b) fptr, 'a -> 'b) T.typ ->
565 :     ('a -> 'b) fptr' * 'a -> 'b
566 :     end

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