chiark / gitweb /
Bug fix
[clg] / gffi / basic-types.lisp
CommitLineData
beae6579 1;; Common Lisp bindings for GTK+ v2.x
2;; Copyright 1999-2005 Espen S. Johnsen <espen@users.sf.net>
3;;
4;; Permission is hereby granted, free of charge, to any person obtaining
5;; a copy of this software and associated documentation files (the
6;; "Software"), to deal in the Software without restriction, including
7;; without limitation the rights to use, copy, modify, merge, publish,
8;; distribute, sublicense, and/or sell copies of the Software, and to
9;; permit persons to whom the Software is furnished to do so, subject to
10;; the following conditions:
11;;
12;; The above copyright notice and this permission notice shall be
13;; included in all copies or substantial portions of the Software.
14;;
15;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18;; IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19;; CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
25168576 23;; $Id: basic-types.lisp,v 1.13 2008-10-08 16:27:09 espen Exp $
beae6579 24
25(in-package "GFFI")
26
27
2c708568 28(deftype byte () '(unsigned-byte 8))
beae6579 29(deftype int ()
30 '(signed-byte #+sbcl #.(sb-sizeof-bits 'sb-alien:int)
31 #+clisp #.(ffi:bitsizeof 'ffi:int)
32 #-(or sbcl clisp) 32))
33(deftype unsigned-int ()
34 '(unsigned-byte #+sbcl #.(sb-sizeof-bits 'sb-alien:int)
35 #+clisp #.(ffi:bitsizeof 'ffi:int)
36 #-(or sbcl clisp) 32))
37(deftype long ()
38 '(signed-byte #+sbcl #.(sb-sizeof-bits 'sb-alien:long)
39 #+clisp #.(ffi:bitsizeof 'ffi:long)
40 #-(or sbcl clisp) 32))
41(deftype unsigned-long ()
42 '(unsigned-byte #+sbcl #.(sb-sizeof-bits 'sb-alien:long)
43 #+clisp #.(ffi:bitsizeof 'ffi:long)
44 #-(or sbcl clisp) 32))
45(deftype short ()
46 '(signed-byte #+sbcl #.(sb-sizeof-bits 'sb-alien:short)
47 #+clisp #.(ffi:bitsizeof 'ffi:short)
48 #-(or sbcl clisp) 16))
49(deftype unsigned-short ()
50 '(unsigned-byte #+sbcl #.(sb-sizeof-bits 'sb-alien:short)
51 #+clisp #.(ffi:bitsizeof 'ffi:short)
52 #-(or sbcl clisp) 16))
53(deftype signed (&optional (size '*)) `(signed-byte ,size))
54(deftype unsigned (&optional (size '*)) `(unsigned-byte ,size))
55(deftype char () 'base-char)
db71d84e 56(deftype pointer-data ()
57 '(unsigned-byte #+sbcl #.(sb-sizeof-bits 'sb-alien:system-area-pointer)
58 #+clisp #.(ffi:bitsizeof 'ffi:c-pointer)
59 #-(or sbcl clisp) 32))
60
beae6579 61(deftype bool (&optional (size '*)) (declare (ignore size)) 'boolean)
62(deftype copy-of (type) type)
63(deftype static (type) type)
64(deftype inlined (type) type)
65
66
67
68(define-type-generic alien-type (type)
69 "Returns the foreign type corresponding to TYPE")
2c708568 70(define-type-generic argument-type (type)
71 "Returns the type to be used in argument declarations for TYPE.")
72(define-type-generic return-type (type)
73 "Returns the type to be used in return type declarations for TYPE.")
beae6579 74(define-type-generic size-of (type &key inlined)
75 "Returns the foreign size of TYPE. The default value of INLINED is
76T for basic C types and NIL for other types.")
90e8bbf6 77(define-type-generic type-alignment (type &key inlined)
78 "Returns the alignment of TYPE. The default value of INLINED is
79T for basic C types and NIL for other types.")
beae6579 80(define-type-generic alien-arg-wrapper (type var arg style form &optional copy-p)
81 "Creates a wrapper around FORM which binds the alien translation of
82ARG to VAR in a way which makes it possible to pass the location of
83VAR in a foreign function call. It should also do any necessary clean
84up before returning the value of FORM.")
85(define-type-generic to-alien-form (type form &optional copy-p)
86 "Returns a form which translates FORM to alien representation. If
87COPY-P is non NIL then any allocated foreign memory must not be
88reclaimed later.")
89(define-type-generic from-alien-form (type form &key ref)
90 "Returns a form which translates FORM from alien to lisp
91representation. REF should be :FREE, :COPY, :STATIC or :TEMP")
92(define-type-generic to-alien-function (type &optional copy-p)
93 "Returns a function of one argument which will translate objects of the given type to alien repesentation. An optional function, taking the origional object and the alien representation as arguments, to clean up after the alien value is not needed any more may be returned as a second argument.")
94(define-type-generic from-alien-function (type &key ref)
95 "Returns a function of one argument which will translate alien objects of the given type to lisp representation. REF should be :FREE, :COPY, :STATIC or :TEMP")
557e2be6 96(define-type-generic alien-typep-form (type alien)
97 "Returns a form evaluating to T if ALIEN is an alien representation of TYPE.")
beae6579 98(define-type-generic callback-wrapper (type var arg form)
99 "Creates a wrapper around FORM which binds the lisp translation of
100ARG to VAR during a C callback.")
101
102(define-type-generic writer-function (type &key temp inlined)
103 "Returns a function taking a value, an address and an optional
104offset which when called will write a reference an object at the given
105location. If TEMP is non NIL then the object is expected to be valid
106as long as the reference exists.")
107(define-type-generic reader-function (type &key ref inlined)
108 "Returns a function taking an address and optional offset which when
109called will return the object at given location. REF should be :READ,
110:PEEK or :GET")
111(define-type-generic destroy-function (type &key temp inlined)
112 "Returns a function taking an address and optional offset which when
25168576 113called will destroy the object at the given location. This may
beae6579 114involve freeing the foreign object being referenced or decreasing it's
115ref. count. If TEMP is non NIL then the reference is expected to
116have been written as temporal.")
25168576 117(define-type-generic copy-function (type &key inlined)
118 "Returns a function taking source/destination addresses and optional
119common offset, which will copy the object at the source location to
120the destination. If INLINED is non NIL, the object is assumed to be
121inlined at the source location and will be inlined at the
122destination.")
beae6579 123
124(define-type-generic unbound-value (type-spec)
125 "Returns a value which should be interpreted as unbound for slots with virtual allocation")
126
127(defun assert-inlined (type inlined-p)
128 (unless inlined-p
129 (error "Type ~A can only be inlined" type)))
130
131(defun assert-not-inlined (type inlined-p)
132 (when inlined-p
133 (error "Type ~A can not be inlined" type)))
134
135
136(define-type-method alien-arg-wrapper ((type t) var arg style form &optional
137 (copy-in-p nil copy-in-given-p))
138 (let ((alien-type (alien-type type)))
139 (cond
140 ((in-arg-p style)
141 (let ((to-alien (if copy-in-given-p
142 (to-alien-form type arg copy-in-p)
143 (to-alien-form type arg))))
144 #+(or cmu sbcl)
145 `(with-alien ((,var ,alien-type ,to-alien))
146 ,form)
147 #+clisp
148 `(ffi:with-c-var (,var ',alien-type ,to-alien)
149 ,form)))
150 ((out-arg-p style)
151 #+(or cmu sbcl)
152 `(with-alien ((,var ,alien-type))
153 (clear-memory (alien-sap (addr ,var)) ,(size-of type))
154 ,form)
155 #+clisp
156 `(ffi:with-c-var (,var ',alien-type)
157 ,form)))))
158
159(define-type-method callback-wrapper ((type t) var arg form)
160 `(let ((,var ,(from-alien-form type arg :ref :temp)))
161 ,form))
162
163(define-type-method alien-type ((type t))
164 (error "No alien type corresponding to the type specifier ~A" type))
165
2c708568 166(define-type-method argument-type ((type t))
167 type)
168
169(define-type-method return-type ((type t))
170 type)
171
beae6579 172(define-type-method to-alien-form ((type t) form &optional copy-p)
173 (declare (ignore form copy-p))
174 (error "Not a valid type specifier for arguments: ~A" type))
175
176(define-type-method to-alien-function ((type t) &optional copy-p)
177 (declare (ignore copy-p))
178 (error "Not a valid type specifier for arguments: ~A" type))
179
180(define-type-method from-alien-form ((type t) form &key ref)
181 (declare (ignore form ref))
182 (error "Not a valid type specifier for return values: ~A" type))
183
184(define-type-method from-alien-function ((type t) &key ref)
185 (declare (ignore ref))
186 (error "Not a valid type specifier for return values: ~A" type))
187
188(define-type-method destroy-function ((type t) &key temp (inlined t inlined-p))
189 (declare (ignore temp))
190 (let ((size (if inlined-p
191 (size-of type :inlined inlined)
192 (size-of type))))
193 #'(lambda (location &optional (offset 0))
194 (clear-memory location size offset))))
195
196(define-type-method copy-function ((type t) &key (inlined t inlined-p))
197 (let ((size (if inlined-p
198 (size-of type :inlined inlined)
199 (size-of type))))
200 #'(lambda (from to &optional (offset 0))
201 (copy-memory (pointer+ from offset) size (pointer+ to offset)))))
202
203(define-type-method to-alien-form ((type real) form &optional copy-p)
204 (declare (ignore type copy-p))
205 form)
206
207(define-type-method to-alien-function ((type real) &optional copy-p)
208 (declare (ignore type copy-p))
209 #'identity)
210
211(define-type-method from-alien-form ((type real) form &key ref)
212 (declare (ignore type ref))
213 form)
214
215(define-type-method from-alien-function ((type real) &key ref)
216 (declare (ignore type ref))
217 #'identity)
218
219
220(define-type-method alien-type ((type integer))
221 (declare (ignore type))
222 (alien-type 'signed-byte))
223
224(define-type-method size-of ((type integer) &key (inlined t))
225 (declare (ignore type))
226 (size-of 'signed-byte :inlined inlined))
227
90e8bbf6 228(define-type-method type-alignment ((type integer) &key (inlined t))
229 (declare (ignore type))
230 (type-alignment 'signed-byte :inlined inlined))
231
beae6579 232(define-type-method writer-function ((type integer) &key temp (inlined t))
233 (declare (ignore temp))
234 (assert-inlined type inlined)
235 (writer-function 'signed-byte))
236
237(define-type-method reader-function ((type integer) &key ref (inlined t))
238 (declare (ignore ref))
239 (assert-inlined type inlined)
240 (reader-function 'signed-byte))
241
242
243;;; Signed Byte
244
245(define-type-method alien-type ((type signed-byte))
246 (destructuring-bind (&optional (size '*))
247 (rest (mklist (type-expand-to 'signed-byte type)))
248 (let ((size (if (eq size '*)
249 (second (type-expand-to 'signed-byte 'int))
250 size)))
251 #+cmu
252 (ecase size
253 ( 8 '(alien:signed 8))
254 (16 '(alien:signed 16))
255 (32 '(alien:signed 32))
256 (64 '(alien:signed 64)))
257 #+sbcl
258 (ecase size
259 ( 8 '(sb-alien:signed 8))
260 (16 '(sb-alien:signed 16))
261 (32 '(sb-alien:signed 32))
262 (64 '(sb-alien:signed 64)))
263 #+clisp
264 (ecase size
265 ( 8 'ffi:sint8)
266 (16 'ffi:sint16)
267 (32 'ffi:sint32)
268 (64 'ffi:sint64)))))
269
270(define-type-method size-of ((type signed-byte) &key (inlined t))
271 (assert-inlined type inlined)
272 (destructuring-bind (&optional (size '*))
273 (rest (mklist (type-expand-to 'signed-byte type)))
274 (let ((size (if (eq size '*)
275 (second (type-expand-to 'signed-byte 'int))
276 size)))
277 (ecase size
278 ( 8 1)
279 (16 2)
280 (32 4)
281 (64 8)))))
282
90e8bbf6 283(define-type-method type-alignment ((type signed-byte) &key (inlined t))
284 (assert-inlined type inlined)
285 (destructuring-bind (&optional (size '*))
286 (rest (mklist (type-expand-to 'signed-byte type)))
287 (let ((size (if (eq size '*)
288 (second (type-expand-to 'signed-byte 'int))
289 size)))
290 #+sbcl(sb-alignment `(sb-alien:signed ,size))
291 #+clisp(ecase size
292 ( 8 (nth-value 1 (ffi:sizeof 'ffi:sint8)))
293 (16 (nth-value 1 (ffi:sizeof 'ffi:sint16)))
294 (32 (nth-value 1 (ffi:sizeof 'ffi:sint32)))
295 (64 (nth-value 1 (ffi:sizeof 'ffi:sint64))))
296 #-(or sbcl clisp) 4)))
297
beae6579 298(define-type-method writer-function ((type signed-byte) &key temp (inlined t))
299 (declare (ignore temp))
300 (assert-inlined type inlined)
301 (destructuring-bind (&optional (size '*))
302 (rest (mklist (type-expand-to 'signed-byte type)))
303 (let ((size (if (eq size '*)
304 (second (type-expand-to 'signed-byte 'int))
305 size)))
306 (ecase size
2c708568 307 ( 8 #'(setf ref-int-8))
308 (16 #'(setf ref-native-int-16))
309 (32 #'(setf ref-native-int-32))
310 (64 #'(setf ref-native-int-64))))))
beae6579 311
312(define-type-method reader-function ((type signed-byte) &key ref (inlined t))
313 (declare (ignore ref))
314 (assert-inlined type inlined)
315 (destructuring-bind (&optional (size '*))
316 (rest (mklist (type-expand-to 'signed-byte type)))
317 (let ((size (if (eq size '*)
318 (second (type-expand-to 'signed-byte 'int))
319 size)))
320 (ecase size
2c708568 321 ( 8 #'ref-int-8)
322 (16 #'ref-native-int-16)
323 (32 #'ref-native-int-32)
324 (64 #'ref-native-int-64)))))
beae6579 325
326
327;;; Unsigned Byte
328
329(define-type-method alien-type ((type unsigned-byte))
330 (destructuring-bind (&optional (size '*))
331 (rest (mklist (type-expand-to 'unsigned-byte type)))
332 (let ((size (if (eq size '*)
333 (second (type-expand-to 'signed-byte 'int))
334 size)))
335 #+cmu
336 (ecase size
337 ( 8 '(alien:unsigned 8))
338 (16 '(alien:unsigned 16))
339 (32 '(alien:unsigned 32))
340 (64 '(alien:unsigned 64)))
341 #+sbcl
342 (ecase size
343 ( 8 '(sb-alien:unsigned 8))
344 (16 '(sb-alien:unsigned 16))
345 (32 '(sb-alien:unsigned 32))
346 (64 '(sb-alien:unsigned 64)))
347 #+clisp
348 (ecase size
349 ( 8 'ffi:uint8)
350 (16 'ffi:uint16)
351 (32 'ffi:uint32)
352 (64 'ffi:uint64)))))
353
354(define-type-method size-of ((type unsigned-byte) &key (inlined t))
355 (assert-inlined type inlined)
356 (destructuring-bind (&optional (size '*))
357 (rest (mklist (type-expand-to 'unsigned-byte type)))
358 (size-of `(signed ,size))))
359
90e8bbf6 360(define-type-method type-alignment ((type unsigned-byte) &key (inlined t))
361 (assert-inlined type inlined)
362 (destructuring-bind (&optional (size '*))
363 (rest (mklist (type-expand-to 'unsigned-byte type)))
364 (type-alignment `(signed ,size))))
365
beae6579 366(define-type-method writer-function ((type unsigned-byte) &key temp (inlined t))
367 (declare (ignore temp))
368 (assert-inlined type inlined)
369 (destructuring-bind (&optional (size '*))
370 (rest (mklist (type-expand-to 'unsigned-byte type)))
371 (let ((size (if (eq size '*)
372 (second (type-expand-to 'signed-byte 'int))
373 size)))
374 (ecase size
2c708568 375 ( 8 #'(setf ref-uint-8))
376 (16 #'(setf ref-native-uint-16))
377 (32 #'(setf ref-native-uint-32))
378 (64 #'(setf ref-native-uint-64))))))
beae6579 379
380(define-type-method reader-function ((type unsigned-byte) &key ref (inlined t))
381 (declare (ignore ref))
382 (assert-inlined type inlined)
383 (destructuring-bind (&optional (size '*))
384 (rest (mklist (type-expand-to 'unsigned-byte type)))
385 (let ((size (if (eq size '*)
386 (second (type-expand-to 'signed-byte 'int))
387 size)))
388 (ecase size
2c708568 389 ( 8 #'ref-uint-8)
390 (16 #'ref-native-uint-16)
391 (32 #'ref-native-uint-32)
392 (64 #'ref-native-uint-64)))))
beae6579 393
394
395;;; Single Float
396
397(define-type-method alien-type ((type single-float))
398 (declare (ignore type))
399 #+cmu 'alien:single-float
400 #+sbcl 'sb-alien:single-float
401 #+clisp 'single-float)
402
2c708568 403(define-type-method argument-type ((type single-float))
404 (declare (ignore type))
405 'number)
406
beae6579 407(define-type-method size-of ((type single-float) &key (inlined t))
408 (assert-inlined type inlined)
409 #+sbcl (sb-sizeof 'sb-alien:float)
410 #+clisp (ffi:sizeof 'single-float)
411 #-(or sbcl clisp) 4)
412
90e8bbf6 413(define-type-method type-alignment ((type single-float) &key (inlined t))
414 (assert-inlined type inlined)
415 #+sbcl (sb-alignment 'single-float)
416 #+clisp (nth-value 1 (ffi:sizeof 'single-float))
417 #-(or sbcl clisp) 4)
418
beae6579 419(define-type-method to-alien-form ((type single-float) form &optional copy-p)
420 (declare (ignore type copy-p))
421 `(coerce ,form 'single-float))
422
423(define-type-method to-alien-function ((type single-float) &optional copy-p)
424 (declare (ignore type copy-p))
425 #'(lambda (number)
426 (coerce number 'single-float)))
427
428(define-type-method writer-function ((type single-float) &key temp (inlined t))
429 (declare (ignore temp))
430 (assert-inlined type inlined)
7c14f6ab 431 #'(lambda (number location &optional (offset 0))
2c708568 432 (setf (ref-native-single-float location offset) (coerce number 'single-float))))
beae6579 433
434(define-type-method reader-function ((type single-float) &key ref (inlined t))
435 (declare (ignore ref))
436 (assert-inlined type inlined)
2c708568 437 #'ref-native-single-float)
beae6579 438
439
440
441;;; Double Float
442
443(define-type-method alien-type ((type double-float))
444 (declare (ignore type))
445 #+cmu 'alien:double-float
446 #+sbcl 'sb-alien:double-float
447 #+clisp 'double-float)
448
2c708568 449(define-type-method argument-type ((type double-float))
450 (declare (ignore type))
451 'number)
452
beae6579 453(define-type-method size-of ((type double-float) &key (inlined t))
454 (assert-inlined type inlined)
455 #+sbcl (sb-sizeof 'sb-alien:double)
456 #+clisp (ffi:sizeof 'double-float)
457 #-(or sbcl clisp) 8)
458
90e8bbf6 459(define-type-method type-alignment ((type double-float) &key (inlined t))
460 (assert-inlined type inlined)
461 #+sbcl (sb-alignment 'double-float)
462 #+clisp (nth-value 1 (ffi:sizeof 'double-float))
463 #-(or sbcl clisp) 4)
464
beae6579 465(define-type-method to-alien-form ((type double-float) form &optional copy-p)
466 (declare (ignore type copy-p))
467 `(coerce ,form 'double-float))
468
469(define-type-method to-alien-function ((type double-float) &optional copy-p)
470 (declare (ignore type copy-p))
471 #'(lambda (number)
472 (coerce number 'double-float)))
473
474(define-type-method writer-function ((type double-float) &key temp (inlined t))
475 (declare (ignore temp))
476 (assert-inlined type inlined)
477 #'(lambda (value location &optional (offset 0))
2c708568 478 (setf (ref-native-double-float location offset) (coerce value 'double-float))))
beae6579 479
480(define-type-method reader-function ((type double-float) &key ref (inlined t))
481 (declare (ignore ref))
482 (assert-inlined type inlined)
2c708568 483 #'ref-native-double-float)
beae6579 484
5fa2eaf1 485(deftype optimized-double-float () 'double-float)
486
487(define-type-method to-alien-form ((type optimized-double-float) form &optional copy-p)
488 (declare (ignore type copy-p))
489 form)
490
2c708568 491(define-type-method argument-type ((type optimized-double-float))
492 (declare (ignore type))
493 'double-float)
494
beae6579 495
496
497;;; Character
498
499(define-type-method alien-type ((type base-char))
500 (declare (ignore type))
501 #+cmu 'c-call:char
502 #+sbcl 'sb-alien:char
503 #+clisp 'ffi:character)
504
505(define-type-method size-of ((type base-char) &key (inlined t))
506 (assert-inlined type inlined)
507 1)
90e8bbf6 508
509(define-type-method type-alignment ((type base-char) &key (inlined t))
510 (assert-inlined type inlined)
511 #+sbcl (sb-alignment 'sb-alien:char)
512 #+clisp (nth-value 1 (ffi:sizeof 'ffi:character))
513 #-(or sbcl clisp) 4)
beae6579 514
515(define-type-method to-alien-form ((type base-char) form &optional copy-p)
516 (declare (ignore type copy-p))
517 form)
518
519(define-type-method to-alien-function ((type base-char) &optional copy-p)
520 (declare (ignore type copy-p))
521 #'identity)
522
523(define-type-method from-alien-form ((type base-char) form &key ref)
524 (declare (ignore type ref))
525 form)
526
527(define-type-method from-alien-function ((type base-char) &key ref)
528 (declare (ignore type ref))
529 #'identity)
530
531(define-type-method writer-function ((type base-char) &key temp (inlined t))
532 (declare (ignore temp))
533 (assert-inlined type inlined)
534 #'(lambda (char location &optional (offset 0))
2c708568 535 (setf (ref-int-8 location offset) (char-code char))))
beae6579 536
537(define-type-method reader-function ((type base-char) &key ref (inlined t))
538 (declare (ignore ref))
539 (assert-inlined type inlined)
540 #'(lambda (location &optional (offset 0))
2c708568 541 (code-char (ref-int-8 location offset))))
beae6579 542
543
544
545;;; String
546
547(defun utf8-length (string)
e846072c 548 "Returns the length including the trailing zero, of STRING encoded as UTF8"
beae6579 549 (1+ (loop
550 for char across string
551 as char-code = (char-code char)
552 sum (cond
553 ((< char-code #x7F) 1)
554 ((< char-code #x7FF) 2)
555 ((< char-code #xFFFF) 3)
556 ((< char-code #x1FFFFF) 4)))))
557
558(defun encode-utf8-string (string &optional location)
4be970ba 559 (let* ((len (utf8-length string))
560 (location (or location (allocate-memory len))))
beae6579 561 (loop
562 for char across string
563 for i from 0
564 as char-code = (char-code char)
565 do (flet ((encode (size)
566 (let ((rem (mod size 6)))
2c708568 567 (setf (ref-uint-8 location i)
beae6579 568 (deposit-field
569 #xFF (byte (- 7 rem) (1+ rem))
570 (ldb (byte rem (- size rem)) char-code)))
571 (loop
572 for pos from (- size rem 6) downto 0 by 6
2c708568 573 do (setf (ref-uint-8 location (incf i))
beae6579 574 (+ 128 (ldb (byte 6 pos) char-code)))))))
575 (cond
2c708568 576 ((< char-code #x80) (setf (ref-uint-8 location i) char-code))
beae6579 577 ((< char-code #x800) (encode 11))
578 ((< char-code #x10000) (encode 16))
4be970ba 579 ((< char-code #x200000) (encode 21)))))
2c708568 580 (setf (ref-uint-8 location (1- len)) 0)
beae6579 581 location))
582
583(defun decode-utf8-string (c-string)
584 (with-output-to-string (string)
585 (loop
586 for i from 0
2c708568 587 as octet = (ref-uint-8 c-string i)
beae6579 588 until (zerop octet)
589 do (flet ((decode (size)
590 (loop
591 with rem = (mod size 6)
592 for pos from (- size rem) downto 0 by 6
593 as code = (dpb (ldb (byte rem 0) octet) (byte rem pos) 0)
594 then (dpb
2c708568 595 (ldb (byte 6 0) (ref-uint-8 c-string (incf i)))
beae6579 596 (byte 6 pos) code)
597 finally (write-char (code-char code) string))))
598 (cond
599 ((< octet 128) (write-char (code-char octet) string))
600 ((< octet 224) (decode 11))
601 ((< octet 240) (decode 16))
602 ((< octet 248) (decode 21)))))))
603
604
605(define-type-method alien-arg-wrapper ((type string) var string style form &optional copy-in-p)
606 (declare (ignore type))
607 (cond
608 ((and (in-arg-p style) copy-in-p)
609 `(with-pointer (,var (encode-utf8-string ,string))
610 ,form))
611 ((and (in-arg-p style) (not (out-arg-p style)))
612 `(with-memory (,var (utf8-length ,string))
613 (encode-utf8-string ,string ,var)
614 ,form))
615 ((and (in-arg-p style) (out-arg-p style))
616 (let ((c-string (make-symbol "C-STRING")))
617 `(with-memory (,c-string (utf8-length ,string))
618 (encode-utf8-string ,string ,c-string)
619 (with-pointer (,var ,c-string)
620 ,form))))
621 ((and (out-arg-p style) (not (in-arg-p style)))
622 `(with-pointer (,var)
623 ,form))))
624
625(define-type-method alien-type ((type string))
626 (declare (ignore type))
627 (alien-type 'pointer))
628
2c708568 629(define-type-method argument-type ((type string))
630 'string)
631
632(define-type-method return-type ((type string))
633 'string)
634
beae6579 635(define-type-method size-of ((type string) &key inlined)
636 (assert-not-inlined type inlined)
637 (size-of 'pointer))
638
90e8bbf6 639(define-type-method type-alignment ((type string) &key inlined)
640 (assert-not-inlined type inlined)
641 (type-alignment 'pointer))
642
beae6579 643(define-type-method to-alien-form ((type string) string &optional copy-p)
644 (declare (ignore type copy-p))
645 `(encode-utf8-string ,string))
646
647(define-type-method to-alien-function ((type string) &optional copy-p)
648 (declare (ignore type))
649 (values
650 #'encode-utf8-string
651 (unless copy-p
652 #'(lambda (string c-string)
653 (declare (ignore string))
654 (deallocate-memory c-string)))))
655
656(define-type-method from-alien-form ((type string) form &key (ref :free))
657 (declare (ignore type))
658 `(let ((c-string ,form))
659 (unless (null-pointer-p c-string)
660 (prog1
661 (decode-utf8-string c-string)
662 ,(when (eq ref :free)
663 `(deallocate-memory c-string))))))
664
665(define-type-method from-alien-function ((type string) &key (ref :free))
666 (declare (ignore type))
667 (if (eq ref :free)
668 #'(lambda (c-string)
669 (unless (null-pointer-p c-string)
670 (prog1
671 (decode-utf8-string c-string)
672 (deallocate-memory c-string))))
673 #'(lambda (c-string)
674 (unless (null-pointer-p c-string)
675 (decode-utf8-string c-string)))))
676
677(define-type-method writer-function ((type string) &key temp inlined)
678 (declare (ignore temp))
679 (assert-not-inlined type inlined)
680 #'(lambda (string location &optional (offset 0))
681 (assert (null-pointer-p (ref-pointer location offset)))
682 (setf (ref-pointer location offset) (encode-utf8-string string))))
683
684(define-type-method reader-function ((type string) &key (ref :read) inlined)
685 (assert-not-inlined type inlined)
686 (ecase ref
687 ((:read :peek)
688 #'(lambda (location &optional (offset 0))
689 (unless (null-pointer-p (ref-pointer location offset))
690 (decode-utf8-string (ref-pointer location offset)))))
691 (:get
692 #'(lambda (location &optional (offset 0))
693 (unless (null-pointer-p (ref-pointer location offset))
694 (prog1
695 (decode-utf8-string (ref-pointer location offset))
696 (deallocate-memory (ref-pointer location offset))
697 (setf (ref-pointer location offset) (make-pointer 0))))))))
698
699(define-type-method destroy-function ((type string) &key temp inlined)
700 (declare (ignore temp))
701 (assert-not-inlined type inlined)
702 #'(lambda (location &optional (offset 0))
703 (unless (null-pointer-p (ref-pointer location offset))
704 (deallocate-memory (ref-pointer location offset))
705 (setf (ref-pointer location offset) (make-pointer 0)))))
706
707(define-type-method copy-function ((type string) &key inlined)
708 (assert-not-inlined type inlined)
709 (lambda (from to &optional (offset 0))
710 (let* ((string (ref-pointer from offset))
711 (length (loop
712 for i from 0
2c708568 713 until (zerop (ref-uint-8 string i))
beae6579 714 finally (return (1+ i)))))
715 (setf (ref-pointer to offset) (copy-memory string length)))))
716
717(define-type-method unbound-value ((type string))
718 (declare (ignore type))
719 nil)
720
721
722
723;;; Pathname
724
725(define-type-method alien-type ((type pathname))
726 (declare (ignore type))
727 (alien-type 'string))
728
2c708568 729(define-type-method argument-type ((type pathname))
730 (declare (ignore type))
731 '(or pathname string))
732
beae6579 733(define-type-method size-of ((type pathname) &key inlined)
734 (assert-not-inlined type inlined)
735 (size-of 'string))
736
90e8bbf6 737(define-type-method type-alignment ((type pathname) &key inlined)
738 (assert-not-inlined type inlined)
739 (type-alignment 'string))
740
beae6579 741(define-type-method alien-arg-wrapper ((type pathname) var pathname style form &optional copy-in-p)
742 (declare (ignore type))
743 (alien-arg-wrapper 'string var `(namestring (translate-logical-pathname ,pathname)) style form copy-in-p))
744
745(define-type-method to-alien-form ((type pathname) path)
746 (declare (ignore type))
747 (to-alien-form 'string `(namestring (translate-logical-pathname ,path))))
748
749(define-type-method to-alien-function ((type pathname) &optional copy-p)
750 (declare (ignore type))
751 (let ((string-function (to-alien-function 'string copy-p)))
752 #'(lambda (path)
753 (funcall string-function (namestring path)))))
754
755(define-type-method from-alien-form ((type pathname) form &key (ref :free))
756 (declare (ignore type))
757 `(parse-namestring ,(from-alien-form 'string form :ref ref)))
758
759(define-type-method from-alien-function ((type pathname) &key (ref :free))
760 (declare (ignore type))
761 (let ((string-function (from-alien-function 'string :ref ref)))
762 #'(lambda (string)
763 (parse-namestring (funcall string-function string)))))
764
765(define-type-method writer-function ((type pathname) &key temp inlined)
766 (declare (ignore temp))
767 (assert-not-inlined type inlined)
768 (let ((string-writer (writer-function 'string)))
769 #'(lambda (path location &optional (offset 0))
770 (funcall string-writer (namestring path) location offset))))
771
772(define-type-method reader-function ((type pathname) &key ref inlined)
773 (declare (ignore ref))
774 (assert-not-inlined type inlined)
775 (let ((string-reader (reader-function 'string)))
776 #'(lambda (location &optional (offset 0))
777 (let ((string (funcall string-reader location offset)))
778 (when string
779 (parse-namestring string))))))
780
781(define-type-method destroy-function ((type pathname) &key temp inlined)
782 (declare (ignore temp))
783 (assert-not-inlined type inlined)
784 (destroy-function 'string))
785
786(define-type-method copy-function ((type pathname) &key inlined)
787 (assert-not-inlined type inlined)
788 (copy-function 'string))
789
790(define-type-method unbound-value ((type pathname))
791 (declare (ignore type))
792 (unbound-value 'string))
793
794
795
796;;; Bool
797
798(define-type-method alien-type ((type bool))
799 (destructuring-bind (&optional (size '*))
800 (rest (mklist (type-expand-to 'bool type)))
801 (alien-type `(signed-byte ,size))))
802
803(define-type-method size-of ((type bool) &key (inlined t))
804 (assert-inlined type inlined)
805 (destructuring-bind (&optional (size '*))
806 (rest (mklist (type-expand-to 'bool type)))
807 (size-of `(signed-byte ,size))))
808
90e8bbf6 809(define-type-method type-alignment ((type bool) &key (inlined t))
810 (assert-inlined type inlined)
811 (destructuring-bind (&optional (size '*))
812 (rest (mklist (type-expand-to 'bool type)))
813 (type-alignment `(signed-byte ,size))))
814
beae6579 815(define-type-method to-alien-form ((type bool) bool &optional copy-p)
816 (declare (ignore type copy-p))
817 `(if ,bool 1 0))
818
819(define-type-method to-alien-function ((type bool) &optional copy-p)
820 (declare (ignore type copy-p))
821 #'(lambda (bool)
822 (if bool 1 0)))
823
824(define-type-method from-alien-form ((type bool) form &key ref)
825 (declare (ignore type ref))
826 `(not (zerop ,form)))
827
828(define-type-method from-alien-function ((type bool) &key ref)
829 (declare (ignore type ref))
830 #'(lambda (bool)
831 (not (zerop bool))))
832
833(define-type-method writer-function ((type bool) &key temp (inlined t))
834 (declare (ignore temp))
835 (assert-inlined type inlined)
836 (destructuring-bind (&optional (size '*))
837 (rest (mklist (type-expand-to 'bool type)))
838 (let ((writer (writer-function `(signed-byte ,size))))
839 #'(lambda (bool location &optional (offset 0))
840 (funcall writer (if bool 1 0) location offset)))))
841
842(define-type-method reader-function ((type bool) &key ref (inlined t))
843 (declare (ignore ref))
844 (assert-inlined type inlined)
845 (destructuring-bind (&optional (size '*))
846 (rest (mklist (type-expand-to 'bool type)))
847 (let ((reader (reader-function `(signed-byte ,size))))
848 #'(lambda (location &optional (offset 0))
849 (not (zerop (funcall reader location offset)))))))
850
851
852
853;;; Boolean
854
855(define-type-method alien-type ((type boolean))
856 (declare (ignore type))
857 (alien-type 'bool))
858
2c708568 859(define-type-method argument-type ((type boolean))
860 (declare (ignore type))
861 t)
862
beae6579 863(define-type-method size-of ((type boolean) &key (inlined t))
864 (assert-inlined type inlined)
865 (size-of 'bool))
866
90e8bbf6 867(define-type-method type-alignment ((type boolean) &key (inlined t))
868 (assert-inlined type inlined)
869 (type-alignment 'bool))
870
beae6579 871(define-type-method to-alien-form ((type boolean) boolean &optional copy-p)
872 (declare (ignore type copy-p))
873 (to-alien-form 'bool boolean))
874
875(define-type-method to-alien-function ((type boolean) &optional copy-p)
876 (declare (ignore type copy-p))
877 (to-alien-function 'bool))
878
879(define-type-method from-alien-form ((type boolean) form &key ref)
880 (declare (ignore type ref))
881 (from-alien-form 'bool form))
882
883(define-type-method from-alien-function ((type boolean) &key ref)
884 (declare (ignore type ref))
885 (from-alien-function 'bool))
886
887(define-type-method writer-function ((type boolean) &key temp (inlined t))
888 (declare (ignore temp))
889 (assert-inlined type inlined)
890 (writer-function 'bool))
891
892(define-type-method reader-function ((type boolean) &key ref (inlined t))
893 (declare (ignore ref))
894 (assert-inlined type inlined)
895 (reader-function 'bool))
896
897
898;;; Or
899
900(define-type-method alien-type ((type or))
901 (let* ((expanded-type (type-expand-to 'or type))
902 (alien-type (alien-type (second expanded-type))))
903 (unless (every #'(lambda (type)
904 (eq alien-type (alien-type type)))
905 (cddr expanded-type))
906 (error "No common alien type specifier for union type: ~A" type))
907 alien-type))
908
2c708568 909(define-type-method argument-type ((type or))
910 (let ((expanded-type (type-expand-to 'or type)))
911 `(or ,@(mapcar #'argument-type (rest expanded-type)))))
912
913
beae6579 914(define-type-method size-of ((type or) &key (inlined nil inlined-p))
915 (loop
e5214c13 916 for subtype in (cdr (type-expand-to 'or type))
beae6579 917 maximize (if inlined-p
e5214c13 918 (size-of subtype :inlined inlined)
beae6579 919 (size-of subtype))))
920
90e8bbf6 921(define-type-method type-alignment ((type or) &key (inlined nil inlined-p))
922 (loop
e5214c13 923 for subtype in (cdr (type-expand-to 'or type))
90e8bbf6 924 maximize (if inlined-p
e5214c13 925 (type-alignment subtype :inlined inlined)
90e8bbf6 926 (type-alignment subtype))))
927
beae6579 928(define-type-method alien-arg-wrapper ((type or) var value style form &optional copy-in-p)
929 (cond
930 ((and (in-arg-p style) (out-arg-p style))
931 `(etypecase ,value
932 ,@(mapcar
933 #'(lambda (type)
934 `(,type ,(alien-arg-wrapper type var value style form copy-in-p)))
935 (rest (type-expand-to 'or type)))))
936 ((in-arg-p style)
2c708568 937 ;; If the unexpanded type has explicit alien-type and
938 ;; to-alien-form methods, we just call the default arg wrapper
939 (if (and
940 (not (eq (first (mklist type)) 'or))
941 (find-type-method 'alien-type type nil)
942 (find-type-method 'to-alien-form type nil))
943 (funcall (find-type-method 'alien-arg-wrapper t) type var value style form copy-in-p)
944 (let ((body (make-symbol "BODY")))
945 `(flet ((,body (,var)
946 ,form))
947 (etypecase ,value
948 ,@(mapcar
949 #'(lambda (type)
950 `(,type ,(alien-arg-wrapper type var value style `(,body ,var) copy-in-p)))
951 (rest (type-expand-to 'or type))))))))
beae6579 952 ((out-arg-p style)
953 #+(or cmu sbcl)
954 `(with-alien ((,var ,(alien-type type)))
955 (clear-memory (alien-sap (addr ,var)) ,(size-of type))
956 ,form)
957 #+clisp
958 `(ffi:with-c-var (,var ',(alien-type type))
959 ,form))))
960
961(define-type-method to-alien-form ((type or) form &optional copy-p)
962 `(let ((value ,form))
963 (etypecase value
964 ,@(mapcar
965 #'(lambda (type)
966 `(,type ,(to-alien-form type 'value copy-p)))
967 (rest (type-expand-to 'or type))))))
968
557e2be6 969(define-type-method from-alien-form ((type or) form &key ref)
970 (declare (ignore ref))
971 `(let ((alien ,form))
972 (cond
973 ,@(loop
974 for (type . rest) on (rest (type-expand-to 'or type))
975 collect
976 `(,(if (endp rest)
977 t
978 (alien-typep-form type 'alien))
979 ,(from-alien-form type 'alien))))))
980
981
982
beae6579 983(define-type-method to-alien-function ((type or) &optional copy-p)
984 (let* ((expanded-type (type-expand-to 'or type))
985 (functions (loop
986 for type in (rest expanded-type)
987 collect (to-alien-function type copy-p))))
988 #'(lambda (value)
989 (loop
990 for function in functions
991 for alt-type in (rest expanded-type)
992 when (typep value alt-type)
993 do (return (funcall function value))
994 finally (error "~S is not of type ~A" value type)))))
995
996
997;;; Pointer
998
999(define-type-method alien-type ((type pointer))
1000 (declare (ignore type))
1001 #+(or cmu sbcl) 'system-area-pointer
1002 #+clisp 'ffi:c-pointer)
1003
1004(define-type-method size-of ((type pointer) &key (inlined t))
1005 (assert-inlined type inlined)
1006 #+sbcl (sb-sizeof 'sb-alien:system-area-pointer)
1007 #+clisp (ffi:sizeof 'ffi:c-pointer)
1008 #-(or sbcl clisp) 4)
1009
90e8bbf6 1010(define-type-method type-alignment ((type pointer) &key (inlined t))
1011 (assert-inlined type inlined)
1012 #+sbcl (sb-alignment 'system-area-pointer)
1013 #+clisp (ffi:sizeof 'ffi:c-pointer)
1014 #-(or sbcl clisp) (size-of 'pointer))
1015
beae6579 1016(define-type-method to-alien-form ((type pointer) form &optional copy-p)
1017 (declare (ignore type copy-p))
1018 form)
1019
1020(define-type-method to-alien-function ((type pointer) &optional copy-p)
1021 (declare (ignore type copy-p))
1022 #'identity)
1023
1024(define-type-method from-alien-form ((type pointer) form &key ref)
1025 (declare (ignore type ref))
1026 form)
1027
1028(define-type-method from-alien-function ((type pointer) &key ref)
1029 (declare (ignore type ref))
1030 #'identity)
1031
1032(define-type-method writer-function ((type pointer) &key temp (inlined t))
1033 (declare (ignore temp))
1034 (assert-inlined type inlined)
1035 #'(setf ref-pointer))
1036
1037(define-type-method reader-function ((type pointer) &key ref (inlined t))
1038 (declare (ignore ref))
1039 (assert-inlined type inlined)
1040 #'ref-pointer)
1041
1042
557e2be6 1043
1044;;; Null Pointer
1045
beae6579 1046(define-type-method alien-type ((type null))
1047 (declare (ignore type))
1048 (alien-type 'pointer))
1049
1050(define-type-method size-of ((type null) &key (inlined t))
1051 (assert-inlined type inlined)
1052 (size-of 'pointer))
1053
557e2be6 1054(define-type-method alien-typep-form ((type null) null)
1055 (declare (ignore type))
1056 `(null-pointer-p ,null))
1057
1058(define-type-method from-alien-form ((type null) null &key ref)
1059 (declare (ignore type null ref))
1060 nil)
1061
beae6579 1062(define-type-method to-alien-form ((type null) null &optional copy-p)
1063 (declare (ignore type copy-p))
1064 `(progn ,null (make-pointer 0)))
1065
1066(define-type-method to-alien-function ((type null) &optional copy-p)
1067 (declare (ignore type copy-p))
1068 #'(lambda (null)
1069 (declare (ignore null))
1070 (make-pointer 0)))
1071
1072
1073(define-type-method alien-type ((type nil))
1074 (declare (ignore type))
1075 #+(or cmu sbcl) 'void
1076 #+clisp nil)
1077
1078(define-type-method from-alien-form ((type nil) form &key ref)
1079 (declare (ignore type ref))
1080 form)
1081
1082(define-type-method from-alien-function ((type nil) &key ref)
1083 (declare (ignore type ref))
1084 #'(lambda (value)
1085 (declare (ignore value))
1086 (values)))
1087
1088(define-type-method to-alien-form ((type nil) form &optional copy-p)
1089 (declare (ignore type copy-p))
1090 form)
1091
1092
1093
1094;;; Callbacks
1095
1096(define-type-method alien-type ((type callback))
1097 (declare (ignore type))
1098 (alien-type 'pointer))
1099
1100(define-type-method to-alien-form ((type callback) callback &optional copy-p)
1101 (declare (ignore type copy-p))
1102 `(callback-address ,callback))
1103
1104
1105
1106;;; Copy-of
1107
2c708568 1108(define-type-method return-type ((type copy-of))
1109 (return-type (second type)))
1110
beae6579 1111(define-type-method from-alien-form ((type copy-of) form &key (ref :copy))
1112 (if (eq ref :copy)
1113 (from-alien-form (second (type-expand-to 'copy-of type)) form :ref ref)
1114 (error "Keyword arg :REF to FROM-ALIEN-FORM should be :COPY for type ~A. It was give ~A" type ref)))
1115
1116(define-type-method from-alien-function ((type copy-of) &key (ref :copy))
1117 (if (eq ref :copy)
1118 (from-alien-function (second (type-expand-to 'copy-of type)) :ref ref)
ea96309c 1119 (error "Keyword arg :REF to FROM-ALIEN-FUNCTION should be :COPY for type ~A. It was give ~A" type ref)))
beae6579 1120
1121(define-type-method to-alien-form ((type copy-of) form &optional (copy-p t))
1122 (if copy-p
1123 (to-alien-form (second (type-expand-to 'copy-of type)) form t)
1124 (error "COPY-P argument to TO-ALIEN-FORM should always be non NIL for type ~A" type)))
1125
1126(define-type-method to-alien-function ((type copy-of) &optional (copy-p t))
1127 (if copy-p
1128 (to-alien-function (second (type-expand-to 'copy-of type)) t)
1129 (error "COPY-P argument to TO-ALIEN-FUNCTION should always be non NIL for type ~A" type)))
1130
1131(define-type-method reader-function ((type copy-of) &key (ref :read) (inlined nil inlined-p))
1132 (if inlined-p
1133 (reader-function (second (type-expand-to 'copy-of type))
1134 :ref (if (eq ref :get) :read ref) :inlined inlined)
1135 (reader-function (second (type-expand-to 'copy-of type))
1136 :ref (if (eq ref :get) :read ref))))
1137
1138(define-type-method destroy-function ((type copy-of) &key temp inlined)
1139 (declare (ignore type temp inlined))
1140 #'(lambda (location &optional offset)
1141 (declare (ignore location offset))))
1142
1143(define-type-method copy-function ((type copy-of) &key (inlined nil inlined-p))
25168576 1144 (if inlined-p
1145 (copy-function (second (type-expand-to 'copy-of type)) :inlined inlined)
1146 (copy-function (second (type-expand-to 'copy-of type)))))
beae6579 1147
1148
1149;;; Static
1150
2c708568 1151(define-type-method return-type ((type static))
1152 (return-type (second type)))
1153
beae6579 1154(define-type-method from-alien-form ((type static) form &key (ref :static))
1155 (if (eq ref :static)
1156 (from-alien-form (second (type-expand-to 'static type)) form :ref ref)
1157 (error "Keyword arg :REF to FROM-ALIEN-FORM should be :STATIC for type ~A. It was give ~A" type ref)))
1158
1159(define-type-method from-alien-function ((type static) &key (ref :static))
1160 (if (eq ref :static)
1161 (from-alien-function (second (type-expand-to 'static type)) :ref ref)
ea96309c 1162 (error "Keyword arg :REF to FROM-ALIEN-FUNCTION should be :STATIC for type ~A. It was give ~A" type ref)))
beae6579 1163
1164(define-type-method to-alien-function ((type static) &optional copy-p)
1165 (if (not copy-p)
1166 (to-alien-function (second (type-expand-to 'static type)) t)
c4261a5c 1167 (error "COPY-P argument to TO-ALIEN-FUNCTION should always be NIL for type ~A" type)))
beae6579 1168
1169(define-type-method to-alien-form ((type static) &optional copy-p)
1170 (if (not copy-p)
c4261a5c 1171 (to-alien-form (second (type-expand-to 'static type)) t)
1172 (error "COPY-P argument to TO-ALIEN-FORM should always be NIL for type ~A" type)))
beae6579 1173
1174(define-type-method reader-function ((type static) &key (ref :read) (inlined nil inlined-p))
1175 (if inlined-p
1176 (reader-function (second (type-expand-to 'static type))
1177 :ref (if (eq ref :get) :read ref) :inlined inlined)
1178 (reader-function (second (type-expand-to 'static type))
1179 :ref (if (eq ref :get) :read ref))))
1180
1181(define-type-method writer-function ((type static) &key temp inlined)
1182 (declare (ignore type temp inlined))
1183 (error "Can't overwrite a static (const) reference"))
1184
1185(define-type-method destroy-function ((type static) &key temp inlined)
1186 (declare (ignore type temp inlined))
1187 #'(lambda (location &optional offset)
1188 (declare (ignore location offset))))
1189
1190(define-type-method copy-function ((type static) &key (inlined nil inlined-p))
25168576 1191 (if inlined-p
1192 (copy-function (second (type-expand-to 'copy-of type)) :inlined inlined)
1193 (copy-function (second (type-expand-to 'copy-of type)))))
beae6579 1194
1195
1196
1197;;; Pseudo type for inlining of types which are not inlined by default
1198
1199(define-type-method size-of ((type inlined) &key (inlined t))
1200 (assert-inlined type inlined)
1201 (size-of (second (type-expand-to 'inlined type)) :inlined t))
1202
2c708568 1203(define-type-method return-type ((type inlined))
1204 (return-type (second type)))
1205
90e8bbf6 1206(define-type-method type-alignment ((type inlined) &key (inlined t))
1207 (assert-inlined type inlined)
1208 (type-alignment (second (type-expand-to 'inlined type)) :inlined t))
1209
beae6579 1210(define-type-method reader-function ((type inlined) &key (ref :read) (inlined t))
1211 (assert-inlined type inlined)
1212 (reader-function (second (type-expand-to 'inlined type)) :ref ref :inlined t))
1213
1214(define-type-method writer-function ((type inlined) &key temp (inlined t))
1215 (assert-inlined type inlined)
1216 (writer-function (second (type-expand-to 'inlined type)) :temp temp :inlined t))
1217
1218(define-type-method destroy-function ((type inlined) &key temp (inlined t))
1219 (assert-inlined type inlined)
1220 (destroy-function (second (type-expand-to 'inlined type)) :temp temp :inlined t))
1221
1222(define-type-method copy-function ((type inlined) &key (inlined t))
1223 (assert-inlined type inlined)
1224 (copy-function (second (type-expand-to 'inlined type)) :inlined t))