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