chiark / gitweb /
Changed order of name arguments to defbindings
[clg] / glib / gforeign.lisp
CommitLineData
560af5c5 1;; Common Lisp bindings for GTK+ v2.0
5cae32e1 2;; Copyright (C) 1999-2001 Espen S. Johnsen <esj@stud.cs.uit.no>
560af5c5 3;;
4;; This library is free software; you can redistribute it and/or
5;; modify it under the terms of the GNU Lesser General Public
6;; License as published by the Free Software Foundation; either
7;; version 2 of the License, or (at your option) any later version.
8;;
9;; This library is distributed in the hope that it will be useful,
10;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12;; Lesser General Public License for more details.
13;;
14;; You should have received a copy of the GNU Lesser General Public
15;; License along with this library; if not, write to the Free Software
16;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
fff7bb35 18;; $Id: gforeign.lisp,v 1.9 2001-05-11 15:57:57 espen Exp $
560af5c5 19
20(in-package "GLIB")
21
22;;;; Type methods
23
24(defvar *type-methods* (make-hash-table))
25
26(defun ensure-type-method-fun (fname)
27 (unless (fboundp fname)
28 (setf
29 (symbol-function fname)
30 #'(lambda (type-spec &rest args)
31 (apply
32 (find-applicable-type-method type-spec fname) type-spec args)))))
33
34(defmacro define-type-method-fun (fname lambda-list)
35 (declare (ignore lambda-list))
36 `(defun ,fname (type-spec &rest args)
37 (apply
38 (find-applicable-type-method type-spec ',fname) type-spec args)))
39
40
41(defun ensure-type-name (type)
42 (etypecase type
43 (symbol type)
44 (pcl::class (class-name type))))
45
46(defun add-type-method (type fname function)
47 (push
48 (cons fname function)
49 (gethash (ensure-type-name type) *type-methods*)))
50
51(defun find-type-method (type fname)
52 (cdr (assoc fname (gethash (ensure-type-name type) *type-methods*))))
53
54(defun find-applicable-type-method (type-spec fname &optional (error t))
55 (flet ((find-superclass-method (class)
56 (when class
57 (dolist (super (cdr (pcl::class-precedence-list class)))
58 (return-if (find-type-method super fname)))))
59 (find-expanded-type-method (type-spec)
60 (multiple-value-bind (expanded-type-spec expanded-p)
61 (type-expand-1 type-spec)
62 (cond
63 (expanded-p
64 (find-applicable-type-method expanded-type-spec fname nil))
65 ((neq type-spec t)
66 (find-applicable-type-method t fname nil))))))
67
68 (or
69 (typecase type-spec
70 (pcl::class
71 (or
72 (find-type-method type-spec fname)
73 (find-superclass-method type-spec)))
74 (symbol
75 (or
76 (find-type-method type-spec fname)
77 (find-expanded-type-method type-spec)
78 (find-superclass-method (find-class type-spec nil))))
79 (cons
80 (or
81 (find-type-method (first type-spec) fname)
82 (find-expanded-type-method type-spec)))
83 (t
84 (error "Invalid type specifier ~A" type-spec)))
85 (and
86 error
87 (error
88 "No applicable method for ~A when called with type specifier ~A"
89 fname type-spec)))))
90
91(defmacro deftype-method (fname type lambda-list &body body)
92 `(progn
93 (ensure-type-method-fun ',fname)
94 (add-type-method ',type ',fname #'(lambda ,lambda-list ,@body))
95 ',fname))
96
5cae32e1 97;; To make the compiler happy
560af5c5 98(eval-when (:compile-toplevel :load-toplevel :execute)
99 (define-type-method-fun translate-type-spec (type-spec))
f5747cee 100 (define-type-method-fun size-of (type-spec))
5cae32e1 101 (define-type-method-fun translate-to-alien (type-spec expr &optional weak-ref))
102 (define-type-method-fun translate-from-alien (type-spec expr &optional weak-ref))
103 (define-type-method-fun cleanup-alien (type-spec sap &otional weak-ref))
104 (define-type-method-fun unreference-alien (type-spec sap)))
105
560af5c5 106
107;;;;
108
109(defvar *type-function-cache* (make-hash-table :test #'equal))
110
111(defun get-cached-function (type-spec fname)
112 (cdr (assoc fname (gethash type-spec *type-function-cache*))))
113
114(defun set-cached-function (type-spec fname function)
115 (push (cons fname function) (gethash type-spec *type-function-cache*))
116 function)
117
118
5cae32e1 119(defun intern-argument-translator (type-spec)
560af5c5 120 (or
5cae32e1 121 (get-cached-function type-spec 'argument-translator)
122 (set-cached-function type-spec 'argument-translator
560af5c5 123 (compile
124 nil
125 `(lambda (object)
126 (declare (ignorable object))
5cae32e1 127 ,(translate-to-alien type-spec 'object t))))))
560af5c5 128
5cae32e1 129(defun intern-return-value-translator (type-spec)
560af5c5 130 (or
5cae32e1 131 (get-cached-function type-spec 'return-value-translator)
132 (set-cached-function type-spec 'return-value-translator
560af5c5 133 (compile
134 nil
135 `(lambda (alien)
136 (declare (ignorable alien))
5cae32e1 137 ,(translate-from-alien type-spec 'alien nil))))))
560af5c5 138
5cae32e1 139(defun intern-cleanup-function (type-spec)
560af5c5 140 (or
141 (get-cached-function type-spec 'cleanup-function)
142 (set-cached-function type-spec 'cleanup-function
143 (compile
144 nil
145 `(lambda (alien)
146 (declare (ignorable alien))
5cae32e1 147 ,(cleanup-alien type-spec 'alien t))))))
560af5c5 148
149
150
5cae32e1 151;; Returns a function to write an object of the specified type
152;; to a memory location
153(defun intern-writer-function (type-spec)
560af5c5 154 (or
155 (get-cached-function type-spec 'writer-function)
156 (set-cached-function type-spec 'writer-function
157 (compile
158 nil
159 `(lambda (value sap offset)
160 (declare (ignorable value sap offset))
161 (setf
162 (,(sap-ref-fname type-spec) sap offset)
5cae32e1 163 ,(translate-to-alien type-spec 'value nil)))))))
560af5c5 164
5cae32e1 165;; Returns a function to read an object of the specified type
166;; from a memory location
167(defun intern-reader-function (type-spec)
560af5c5 168 (or
169 (get-cached-function type-spec 'reader-function)
170 (set-cached-function type-spec 'reader-function
171 (compile
172 nil
173 `(lambda (sap offset)
174 (declare (ignorable sap offset))
175 ,(translate-from-alien
5cae32e1 176 type-spec `(,(sap-ref-fname type-spec) sap offset) t))))))
560af5c5 177
5cae32e1 178(defun intern-destroy-function (type-spec)
179 (if (atomic-type-p type-spec)
180 #'(lambda (sap offset)
181 (declare (ignore sap offset)))
182 (or
183 (get-cached-function type-spec 'destroy-function)
184 (set-cached-function type-spec 'destroy-function
185 (compile
186 nil
187 `(lambda (sap offset)
188 (declare (ignorable sap offset))
189 ,(unreference-alien
190 type-spec `(,(sap-ref-fname type-spec) sap offset))))))))
560af5c5 191
192
193
194;;;;
195
f5747cee 196(defconstant +bits-per-unit+ 8
197 "Number of bits in an addressable unit (byte)")
198
199;; Sizes of fundamental C types in addressable units
200(defconstant +size-of-short+ 2)
560af5c5 201(defconstant +size-of-int+ 4)
f5747cee 202(defconstant +size-of-long+ 4)
560af5c5 203(defconstant +size-of-sap+ 4)
204(defconstant +size-of-float+ 4)
205(defconstant +size-of-double+ 8)
206
207(defun sap-ref-unsigned (sap offset)
208 (sap-ref-32 sap offset))
209
210(defun sap-ref-signed (sap offset)
211 (signed-sap-ref-32 sap offset))
212
213(defun sap-ref-fname (type-spec)
214 (let ((alien-type-spec (mklist (translate-type-spec type-spec))))
215 (ecase (first alien-type-spec)
216 (unsigned
217 (ecase (second alien-type-spec)
218 (8 'sap-ref-8)
219 (16 'sap-ref-16)
220 (32 'sap-ref-32)
221 (64 'sap-ref-64)))
222 (signed
223 (ecase (second alien-type-spec)
224 (8 'signed-sap-ref-8)
225 (16 'signed-sap-ref-16)
226 (32 'signed-sap-ref-32)
227 (64 'signed-sap-ref-64)))
228 (system-area-pointer 'sap-ref-sap)
229 (single-float 'sap-ref-single)
230 (double-float 'sap-ref-double))))
231
232
560af5c5 233;;;; Foreign function call interface
234
235(defvar *package-prefix* nil)
236
237(defun set-package-prefix (prefix &optional (package *package*))
238 (let ((package (find-package package)))
239 (delete-if #'(lambda (assoc) (eq (car assoc) package)) *package-prefix*)
240 (push (cons package prefix) *package-prefix*))
241 prefix)
242
243(defun package-prefix (&optional (package *package*))
244 (let ((package (find-package package)))
245 (or
246 (cdr (assoc package *package-prefix*))
247 (substitute #\_ #\- (string-downcase (package-name package))))))
248
5cae32e1 249(defun find-prefix-package (prefix)
250 (or
251 (car (rassoc (string-downcase prefix) *package-prefix* :test #'string=))
252 (find-package (string-upcase prefix))))
253
560af5c5 254(defmacro use-prefix (prefix &optional (package *package*))
255 `(eval-when (:compile-toplevel :load-toplevel :execute)
256 (set-package-prefix ,prefix ,package)))
257
258
5cae32e1 259(defun default-alien-fname (lisp-name)
560af5c5 260 (let* ((lisp-name-string
261 (if (char= (char (the simple-string (string lisp-name)) 0) #\%)
262 (subseq (the simple-string (string lisp-name)) 1)
263 (string lisp-name)))
264 (prefix (package-prefix *package*))
265 (name (substitute #\_ #\- (string-downcase lisp-name-string))))
266 (if (or (not prefix) (string= prefix ""))
267 name
268 (format nil "~A_~A" prefix name))))
269
5cae32e1 270(defun default-alien-type-name (type-name)
271 (let ((prefix (package-prefix *package*)))
272 (apply
273 #'concatenate
274 'string
275 (mapcar
276 #'string-capitalize
277 (cons prefix (split-string (symbol-name type-name) #\-))))))
278
279(defun default-type-name (alien-name)
280 (let ((parts
281 (mapcar
282 #'string-upcase
283 (split-string-if alien-name #'upper-case-p))))
284 (intern
285 (concatenate-strings
286 (rest parts) #\-) (find-prefix-package (first parts)))))
287
288
289(defmacro defbinding (name lambda-list return-type-spec &rest docs/args)
fff7bb35 290 (multiple-value-bind (lisp-name c-name)
560af5c5 291 (if (atom name)
fff7bb35 292 (values name (default-alien-fname name))
293 (values-list name))
294
560af5c5 295 (let ((supplied-lambda-list lambda-list)
296 (docs nil)
297 (args nil))
298 (dolist (doc/arg docs/args)
299 (if (stringp doc/arg)
300 (push doc/arg docs)
301 (progn
302 (destructuring-bind (expr type &optional (style :in)) doc/arg
a27ed65c 303 (unless (member style '(:in :out :in-out))
560af5c5 304 (error "Bogus argument style ~S in ~S." style doc/arg))
a27ed65c 305 (when (and
306 (not supplied-lambda-list)
307 (namep expr) (member style '(:in :in-out)))
560af5c5 308 (push expr lambda-list))
309 (push
310 (list (if (namep expr) expr (gensym)) expr type style) args)))))
311
5cae32e1 312 (%defbinding
560af5c5 313 c-name lisp-name (or supplied-lambda-list (nreverse lambda-list))
314 return-type-spec (reverse docs) (reverse args)))))
315
560af5c5 316#+cmu
5cae32e1 317(defun %defbinding (foreign-name lisp-name lambda-list
318 return-type-spec docs args)
560af5c5 319 (ext:collect ((alien-types) (alien-bindings) (alien-parameters)
f5747cee 320 (alien-values) (alien-deallocators))
560af5c5 321 (dolist (arg args)
322 (destructuring-bind (var expr type-spec style) arg
323 (let ((declaration (translate-type-spec type-spec))
5cae32e1 324 (deallocation (cleanup-alien type-spec expr t)))
560af5c5 325 (cond
a27ed65c 326 ((member style '(:out :in-out))
560af5c5 327 (alien-types `(* ,declaration))
328 (alien-parameters `(addr ,var))
a27ed65c 329 (alien-bindings
330 `(,var ,declaration
331 ,@(when (eq style :in-out)
5cae32e1 332 (list (translate-to-alien type-spec expr t)))))
333 (alien-values (translate-from-alien type-spec var nil)))
560af5c5 334 (deallocation
335 (alien-types declaration)
336 (alien-bindings
5cae32e1 337 `(,var ,declaration ,(translate-to-alien type-spec expr t)))
560af5c5 338 (alien-parameters var)
f5747cee 339 (alien-deallocators deallocation))
560af5c5 340 (t
341 (alien-types declaration)
5cae32e1 342 (alien-parameters (translate-to-alien type-spec expr t)))))))
560af5c5 343
344 (let ((alien-funcall `(alien-funcall ,lisp-name ,@(alien-parameters))))
345 `(defun ,lisp-name ,lambda-list
346 ,@docs
347 (with-alien ((,lisp-name
348 (function
349 ,(translate-type-spec return-type-spec)
350 ,@(alien-types))
351 :extern ,foreign-name)
352 ,@(alien-bindings))
353 ,(if return-type-spec
354 `(let ((result
5cae32e1 355 ,(translate-from-alien return-type-spec alien-funcall nil)))
f5747cee 356 ,@(alien-deallocators)
560af5c5 357 (values result ,@(alien-values)))
358 `(progn
359 ,alien-funcall
f5747cee 360 ,@(alien-deallocators)
560af5c5 361 (values ,@(alien-values)))))))))
362
7479d92c 363
364(defun mkbinding (name rettype &rest types)
365 (declare (optimize (ext:inhibit-warnings 3)))
366 (let* ((ftype
367 `(function ,@(mapcar #'translate-type-spec (cons rettype types))))
368 (alien
369 (alien::%heap-alien
370 (alien::make-heap-alien-info
371 :type (alien::parse-alien-type ftype)
372 :sap-form (system:foreign-symbol-address name))))
373 (translate-arguments (mapcar #'intern-return-value-translator types))
374 (translate-return-value (intern-return-value-translator rettype))
375 (cleanup-arguments (mapcar #'intern-cleanup-function types)))
376
377 #'(lambda (&rest args)
378 (map-into args #'funcall translate-arguments args)
379 (prog1
380 (funcall
381 translate-return-value (apply #'alien:alien-funcall alien args))
382 (mapc #'funcall cleanup-arguments args)))))
560af5c5 383
384
f5747cee 385;;;; Definitons and translations of fundamental types
560af5c5 386
5cae32e1 387(deftype long (&optional (min '*) (max '*)) `(integer ,min ,max))
388(deftype unsigned-long (&optional (min '*) (max '*)) `(integer ,min ,max))
389(deftype int (&optional (min '*) (max '*)) `(long ,min ,max))
390(deftype unsigned-int (&optional (min '*) (max '*)) `(unsigned-long ,min ,max))
391(deftype short (&optional (min '*) (max '*)) `(int ,min ,max))
392(deftype unsigned-short (&optional (min '*) (max '*)) `(unsigned-int ,min ,max))
393(deftype signed (&optional (size '*)) `(signed-byte ,size))
394(deftype unsigned (&optional (size '*)) `(signed-byte ,size))
395(deftype char () 'base-char)
396(deftype pointer () 'system-area-pointer)
397(deftype boolean (&optional (size '*))
560af5c5 398 (declare (ignore size))
399 `(member t nil))
5cae32e1 400(deftype invalid () nil)
560af5c5 401
5cae32e1 402(defun atomic-type-p (type-spec)
403 (or
404 (eq type-spec 'pointer)
405 (not (eq (translate-type-spec type-spec) 'system-area-pointer))))
560af5c5 406
f5747cee 407
5cae32e1 408(deftype-method cleanup-alien t (type-spec sap &optional weak-ref)
409 (declare (ignore type-spec sap weak-ref))
560af5c5 410 nil)
411
412
5cae32e1 413(deftype-method translate-to-alien integer (type-spec number &optional weak-ref)
414 (declare (ignore type-spec weak-ref))
560af5c5 415 number)
416
5cae32e1 417(deftype-method translate-from-alien integer (type-spec number &optional weak-ref)
418 (declare (ignore type-spec weak-ref))
560af5c5 419 number)
420
421
422(deftype-method translate-type-spec fixnum (type-spec)
423 (declare (ignore type-spec))
f5747cee 424 (translate-type-spec 'signed))
425
426(deftype-method size-of fixnum (type-spec)
427 (declare (ignore type-spec))
428 (size-of 'signed))
560af5c5 429
5cae32e1 430(deftype-method translate-to-alien fixnum (type-spec number &optional weak-ref)
431 (declare (ignore type-spec weak-ref))
560af5c5 432 number)
433
5cae32e1 434(deftype-method translate-from-alien fixnum (type-spec number &optional weak-ref)
435 (declare (ignore type-spec weak-ref))
560af5c5 436 number)
437
438
439(deftype-method translate-type-spec long (type-spec)
440 (declare (ignore type-spec))
f5747cee 441 `(signed ,(* +bits-per-unit+ +size-of-long+)))
442
443(deftype-method size-of long (type-spec)
444 (declare (ignore type-spec))
445 +size-of-long+)
560af5c5 446
447
448(deftype-method translate-type-spec unsigned-long (type-spec)
449 (declare (ignore type-spec))
f5747cee 450 `(unsigned ,(* +bits-per-unit+ +size-of-long+)))
451
452(deftype-method size-of unsigned-long (type-spec)
453 (declare (ignore type-spec))
454 +size-of-long+)
455
456
457(deftype-method translate-type-spec int (type-spec)
458 (declare (ignore type-spec))
459 `(signed ,(* +bits-per-unit+ +size-of-int+)))
460
461(deftype-method size-of int (type-spec)
462 (declare (ignore type-spec))
463 +size-of-int+)
464
465
466(deftype-method translate-type-spec unsigned-int (type-spec)
467 (declare (ignore type-spec))
5cae32e1 468 `(unsigned ,(* +bits-per-unit+ +size-of-int+)))
f5747cee 469
470(deftype-method size-of unsigned-int (type-spec)
471 (declare (ignore type-spec))
472 +size-of-int+)
560af5c5 473
474
475(deftype-method translate-type-spec short (type-spec)
476 (declare (ignore type-spec))
f5747cee 477 `(signed ,(* +bits-per-unit+ +size-of-short+)))
478
479(deftype-method size-of short (type-spec)
480 (declare (ignore type-spec))
481 +size-of-short+)
560af5c5 482
483
484(deftype-method translate-type-spec unsigned-short (type-spec)
485 (declare (ignore type-spec))
f5747cee 486 `(unsigned ,(* +bits-per-unit+ +size-of-short+)))
487
488(deftype-method size-of unsigned-short (type-spec)
489 (declare (ignore type-spec))
490 +size-of-short+)
560af5c5 491
492
493(deftype-method translate-type-spec signed-byte (type-spec)
f5747cee 494 (let ((size (second (mklist (type-expand-to 'signed-byte type-spec)))))
495 `(signed
496 ,(cond
497 ((member size '(nil *)) (* +bits-per-unit+ +size-of-int+))
498 (t size)))))
499
500(deftype-method size-of signed-byte (type-spec)
501 (let ((size (second (mklist (type-expand-to 'signed-byte type-spec)))))
502 (cond
503 ((member size '(nil *)) +size-of-int+)
504 (t (/ size +bits-per-unit+)))))
560af5c5 505
5cae32e1 506(deftype-method translate-to-alien signed-byte (type-spec number &optional weak-ref)
507 (declare (ignore type-spec weak-ref))
560af5c5 508 number)
509
f5747cee 510(deftype-method translate-from-alien signed-byte
5cae32e1 511 (type-spec number &optional weak-ref)
512 (declare (ignore type-spec weak-ref))
560af5c5 513 number)
514
515
516(deftype-method translate-type-spec unsigned-byte (type-spec)
f5747cee 517 (let ((size (second (mklist (type-expand-to 'unsigned-byte type-spec)))))
518 `(signed
519 ,(cond
520 ((member size '(nil *)) (* +bits-per-unit+ +size-of-int+))
521 (t size)))))
522
523(deftype-method size-of unsigned-byte (type-spec)
524 (let ((size (second (mklist (type-expand-to 'unsigned-byte type-spec)))))
525 (cond
526 ((member size '(nil *)) +size-of-int+)
527 (t (/ size +bits-per-unit+)))))
528
5cae32e1 529(deftype-method translate-to-alien unsigned-byte (type-spec number &optional weak-ref)
530 (declare (ignore type-spec weak-ref))
560af5c5 531 number)
532
f5747cee 533(deftype-method translate-from-alien unsigned-byte
5cae32e1 534 (type-spec number &optional weak-ref)
535 (declare (ignore type-spec weak-ref))
560af5c5 536 number)
537
538
539(deftype-method translate-type-spec single-float (type-spec)
540 (declare (ignore type-spec))
541 'single-float)
542
f5747cee 543(deftype-method size-of single-float (type-spec)
544 (declare (ignore type-spec))
545 +size-of-float+)
546
5cae32e1 547(deftype-method translate-to-alien single-float (type-spec number &optional weak-ref)
548 (declare (ignore type-spec weak-ref))
560af5c5 549 number)
550
f5747cee 551(deftype-method translate-from-alien single-float
5cae32e1 552 (type-spec number &optional weak-ref)
553 (declare (ignore type-spec weak-ref))
560af5c5 554 number)
555
556
557(deftype-method translate-type-spec double-float (type-spec)
558 (declare (ignore type-spec))
559 'double-float)
560
f5747cee 561(deftype-method size-of double-float (type-spec)
562 (declare (ignore type-spec))
563 +size-of-double+)
564
5cae32e1 565(deftype-method translate-to-alien double-float (type-spec number &optional weak-ref)
566 (declare (ignore type-spec weak-ref))
560af5c5 567 number)
568
f5747cee 569(deftype-method translate-from-alien double-float
5cae32e1 570 (type-spec number &optional weak-ref)
571 (declare (ignore type-spec weak-ref))
560af5c5 572 number)
573
574
575(deftype-method translate-type-spec base-char (type-spec)
576 (declare (ignore type-spec))
5cae32e1 577 `(unsigned ,+bits-per-unit+))
f5747cee 578
579(deftype-method size-of base-char (type-spec)
580 (declare (ignore type-spec))
581 1)
560af5c5 582
5cae32e1 583(deftype-method translate-to-alien base-char (type-spec char &optional weak-ref)
584 (declare (ignore type-spec weak-ref))
560af5c5 585 `(char-code ,char))
586
5cae32e1 587(deftype-method translate-from-alien base-char (type-spec code &optional weak-ref)
588 (declare (ignore type-spec weak-ref))
560af5c5 589 `(code-char ,code))
590
591
592(deftype-method translate-type-spec string (type-spec)
593 (declare (ignore type-spec))
594 'system-area-pointer)
595
f5747cee 596(deftype-method size-of string (type-spec)
597 (declare (ignore type-spec))
598 +size-of-sap+)
599
5cae32e1 600(deftype-method translate-to-alien string (type-spec string &optional weak-ref)
601 (declare (ignore type-spec weak-ref))
602 `(let ((string ,string))
603 ;; Always copy strings to prevent seg fault due to GC
604 (copy-memory
605 (make-pointer (1+ (kernel:get-lisp-obj-address string)))
606 (1+ (length string)))))
560af5c5 607
f5747cee 608(deftype-method translate-from-alien string
5cae32e1 609 (type-spec c-string &optional weak-ref)
560af5c5 610 (declare (ignore type-spec))
5cae32e1 611 `(let ((c-string ,c-string))
612 (unless (null-pointer-p c-string)
560af5c5 613 (prog1
5cae32e1 614 (c-call::%naturalize-c-string c-string)
615 ;,(unless weak-ref `(deallocate-memory c-string))
9bb7e4a2 616 ))))
560af5c5 617
5cae32e1 618(deftype-method cleanup-alien string (type-spec c-string &optional weak-ref)
560af5c5 619 (declare (ignore type-spec))
5cae32e1 620 (when weak-ref
621 (unreference-alien type-spec c-string)))
560af5c5 622
5cae32e1 623(deftype-method unreference-alien string (type-spec c-string)
7479d92c 624 (declare (ignore type-spec))
5cae32e1 625 `(let ((c-string ,c-string))
626 (unless (null-pointer-p c-string)
627 (deallocate-memory c-string))))
628
560af5c5 629
630(deftype-method translate-type-spec boolean (type-spec)
f5747cee 631 (translate-type-spec
632 (cons 'unsigned (cdr (mklist (type-expand-to 'boolean type-spec))))))
633
634(deftype-method size-of boolean (type-spec)
635 (size-of
636 (cons 'unsigned (cdr (mklist (type-expand-to 'boolean type-spec))))))
560af5c5 637
5cae32e1 638(deftype-method translate-to-alien boolean (type-spec boolean &optional weak-ref)
639 (declare (ignore type-spec weak-ref))
560af5c5 640 `(if ,boolean 1 0))
641
5cae32e1 642(deftype-method translate-from-alien boolean (type-spec int &optional weak-ref)
643 (declare (ignore type-spec weak-ref))
560af5c5 644 `(not (zerop ,int)))
645
646
f5747cee 647(deftype-method translate-type-spec or (union-type)
648 (let* ((member-types (cdr (type-expand-to 'or union-type)))
649 (alien-type (translate-type-spec (first member-types))))
650 (dolist (type (cdr member-types))
651 (unless (eq alien-type (translate-type-spec type))
652 (error "No common alien type specifier for union type: ~A" union-type)))
653 alien-type))
654
655(deftype-method size-of or (union-type)
656 (size-of (first (cdr (type-expand-to 'or union-type)))))
560af5c5 657
5cae32e1 658(deftype-method translate-to-alien or (union-type-spec expr &optional weak-ref)
560af5c5 659 (destructuring-bind (name &rest type-specs)
660 (type-expand-to 'or union-type-spec)
661 (declare (ignore name))
662 `(let ((value ,expr))
663 (etypecase value
664 ,@(map
665 'list
9bb7e4a2 666 #'(lambda (type-spec)
5cae32e1 667 (list type-spec (translate-to-alien type-spec 'value weak-ref)))
9bb7e4a2 668 type-specs)))))
560af5c5 669
670
560af5c5 671(deftype-method translate-type-spec system-area-pointer (type-spec)
672 (declare (ignore type-spec))
673 'system-area-pointer)
674
f5747cee 675(deftype-method size-of system-area-pointer (type-spec)
676 (declare (ignore type-spec))
677 +size-of-sap+)
678
5cae32e1 679(deftype-method translate-to-alien system-area-pointer (type-spec sap &optional weak-ref)
680 (declare (ignore type-spec weak-ref))
560af5c5 681 sap)
682
f5747cee 683(deftype-method translate-from-alien system-area-pointer
5cae32e1 684 (type-spec sap &optional weak-ref)
685 (declare (ignore type-spec weak-ref))
560af5c5 686 sap)
687
688
689(deftype-method translate-type-spec null (type-spec)
690 (declare (ignore type-spec))
691 'system-area-pointer)
692
5cae32e1 693(deftype-method translate-to-alien null (type-spec expr &optional weak-ref)
694 (declare (ignore type-spec expr weak-ref))
560af5c5 695 `(make-pointer 0))
696
697
698(deftype-method translate-type-spec nil (type-spec)
699 (declare (ignore type-spec))
700 'void)
7479d92c 701
702(deftype-method translate-from-alien nil (type-spec expr &optional weak-ref)
703 (declare (ignore type-spec weak-ref))
704 `(progn
705 ,expr
706 (values)))