Changeset 450
- Timestamp:
- Feb 1, 2004, 5:17:45 AM (21 years ago)
- Location:
- trunk/ccl/examples
- Files:
-
- 2 edited
-
objc-clos.lisp (modified) (8 diffs)
-
objc-runtime.lisp (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/ccl/examples/objc-clos.lisp
r434 r450 47 47 (package-force-export "NS") 48 48 49 (defparameter *objc-import-private-ivars* t "When true, the CLASS-DIRECT-SLOTS of imported ObjC classes will contain slot definitions for instance variables whose name starts with an underscore. Note that this may exacerbate compatibility problems.") 50 49 51 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 50 52 ;;;; Testing ;;;; … … 80 82 81 83 (defvar *objc-object-slot-vectors* (make-hash-table :test #'eql)) 84 (defvar *objc-canonical-instances* (make-hash-table :test #'eql :weak :value)) 85 86 (defun raw-macptr-for-instance (instance) 87 (let* ((p (%null-ptr))) 88 (%set-macptr-domain p 1) ; not an ObjC object, but EQL to one 89 (%setf-macptr p instance) 90 p)) 91 92 (defun register-canonical-objc-instance (instance raw-ptr) 93 ;(terminate-when-unreachable instance) 94 ;(retain-objc-instance instance) 95 (setf (gethash raw-ptr *objc-canonical-instances*) instance)) 96 97 (defun canonicalize-objc-instance (instance) 98 (or (gethash instance *objc-canonical-instances*) 99 (register-canonical-objc-instance 100 (setq instance (%inc-ptr instance 0)) 101 (raw-macptr-for-instance instance)))) 82 102 83 103 (defun recognize-objc-object (p) … … 97 117 (ecase flags 98 118 (#.objc-flag-instance (id->objc-class index)) 99 (#.objc-flag-class ( id->objc-metaclass index))119 (#.objc-flag-class (objc-class-id->objc-metaclass index)) 100 120 (#.objc-flag-metaclass *objc-metaclass-class*)))) 101 121 … … 113 133 (ecase flags 114 134 (#.objc-flag-instance (id->objc-class-wrapper index)) 115 (#.objc-flag-class (id->objc-metaclass-wrapper index))135 (#.objc-flag-class (id->objc-metaclass-wrapper (objc-class-id->objc-metaclass-id index))) 116 136 (#.objc-flag-metaclass (%class.own-wrapper *objc-metaclass-class*))))) 117 137 … … 197 217 (defmethod print-object ((o objc:objc-object) stream) 198 218 (print-unreadable-object (o stream :type t) 199 (format stream "~a (#x~x)" (nsobject-description o) (%ptr-to-int o)))) 219 (format stream 220 (if (typep o 'ns::ns-string) 221 "~s (#x~x)" 222 "~a (#x~x)") 223 (nsobject-description o) (%ptr-to-int o)))) 200 224 201 225 … … 301 325 (with-macptrs ((ivars (pref c :objc_class.ivars))) 302 326 (unless (%null-ptr-p ivars) 303 (loop with ns-package = (find-package "NS") 304 with n = (pref ivars :objc_ivar_list.ivar_count) 305 with state = (make-ivar-parse-state c) 306 for i from 1 to n 307 for ivar = (pref ivars :objc_ivar_list.ivar_list) 308 then (%inc-ptr ivar (record-length :objc_ivar)) 309 for name = (%get-cstring (pref ivar :objc_ivar.ivar_name)) 310 for sym = (compute-lisp-name name ns-package) 311 when (eql (schar name 0) #\_) 312 do (unexport sym ns-package) 313 ;do (format t "~S: ~S~%" name (pref ivar :objc_ivar.ivar_offset)) 314 collect 315 (make-direct-slot-definition-from-ivar 316 state 317 (pref ivar :objc_ivar.ivar_offset) 318 (with-string-from-cstring 319 (s (pref ivar :objc_ivar.ivar_type)) 320 (objc-foreign-type-for-ivar s)) 321 c 322 (list 323 :name sym 324 :allocation :instance 325 :class c ))))))) 327 (let* ((ns-package (find-package "NS")) 328 (n (pref ivars :objc_ivar_list.ivar_count)) 329 (state (make-ivar-parse-state c))) 330 (collect ((dslotds)) 331 (do* ((i 0 (1+ i)) 332 (ivar (pref ivars :objc_ivar_list.ivar_list) 333 (%inc-ptr ivar (record-length :objc_ivar)))) 334 ((= i n) (dslotds)) 335 (declare (fixnum i)) 336 (with-macptrs ((nameptr (pref ivar :objc_ivar.ivar_name))) 337 (let* ((is-private (eql (%get-unsigned-byte nameptr 0) 338 (char-code #\_)))) 339 (when (or (not is-private) 340 *objc-import-private-ivars*) 341 (let* ((name (%get-cstring nameptr)) 342 (sym (compute-lisp-name name ns-package))) 343 (when is-private 344 (unexport sym ns-package)) 345 (dslotds 346 (make-direct-slot-definition-from-ivar 347 state 348 (pref ivar :objc_ivar.ivar_offset) 349 (with-string-from-cstring 350 (s (pref ivar :objc_ivar.ivar_type)) 351 (objc-foreign-type-for-ivar s)) 352 c 353 (list 354 :name sym 355 :allocation :instance 356 :class c )))))))))))))) 326 357 327 358 (defun make-direct-slot-definition-from-ivar (state … … 493 524 (values #'%get-single-float #'%set-single-float)) 494 525 (foreign-pointer-type 495 (values #'%get-ptr #'%set-ptr)) 526 ;; If we're pointing to a structure whose first field is 527 ;; a pointer to a structure named :OBJC_CLASS, we're of 528 ;; type :ID and can (fairly) safely use %GET-PTR. 529 ;; Otherwise, reference the field as a raw macptr. 530 (let* ((to (foreign-pointer-type-to ftype))) 531 (if 532 (and (typep to 'foreign-record-type) 533 (eq :struct (foreign-record-type-kind to)) 534 (progn 535 (ensure-foreign-type-bits to) 536 (let* ((first-field (car (foreign-record-type-fields to))) 537 (first-field-type 538 (if first-field 539 (foreign-record-field-type first-field)))) 540 (and (typep first-field-type 'foreign-pointer-type) 541 (let* ((first-to (foreign-pointer-type-to 542 first-field-type))) 543 (and (typep first-to 'foreign-record-type) 544 (eq :struct 545 (foreign-record-type-kind first-to)) 546 (eq :objc_class 547 (foreign-record-type-name first-to)))))))) 548 (values #'%get-ptr #'%set-ptr) 549 (values #'(lambda (ptr offset) 550 (let* ((p (%null-ptr))) 551 (%set-macptr-domain p 1) 552 (%setf-macptr p (%get-ptr ptr offset)))) 553 #'%set-ptr)))) 496 554 (foreign-mem-block-type 497 555 (let* ((nbytes (%foreign-type-or-record-size ftype :bytes))) … … 661 719 (unless (%null-ptr-p instance) 662 720 (let* ((len (length (%wrapper-instance-slots (class-own-wrapper class)))) 721 (raw-ptr (raw-macptr-for-instance instance)) 663 722 (slot-vector 664 723 (unless (zerop len) 665 724 (allocate-typed-vector :slot-vector (1+ len) (%slot-unbound-marker))))) 666 (setf (slot-vector.instance slot-vector) instance) 667 (setf (gethash instance *objc-object-slot-vectors*) slot-vector) 668 (terminate-when-unreachable instance) 669 (retain-obcj-object instance) 670 instance)))) 725 (setf (slot-vector.instance slot-vector) raw-ptr) 726 (register-canonical-objc-instance instance raw-ptr))))) 671 727 672 728 (defmethod terminate ((instance objc:objc-object)) -
trunk/ccl/examples/objc-runtime.lisp
r433 r450 68 68 69 69 70 ; (let* ((metaclass-name (intern (concatenate 'string "+" (string class-name)) (symbol-package class-name)))71 72 70 73 71 (let* ((objc-class-map (make-splay-tree #'%ptr-eql … … 85 83 (objc-class-lock (make-lock)) 86 84 (next-objc-class-id 0) 85 (next-objc-metaclass-id 0) 87 86 (class-table-size 1024) 88 87 (c (make-array 1024)) … … 91 90 (mw (make-array 1024 :initial-element nil)) 92 91 (csv (make-array 1024)) 93 (msv (make-array 1024))) 94 95 (flet ((assign-next-class-id () 96 (let* ((id next-objc-class-id)) 97 (if (= (incf next-objc-class-id) class-table-size) 98 (let* ((old-size class-table-size) 99 (new-size (* 2 class-table-size))) 100 (declare (fixnum old-size new-size)) 101 (macrolet ((extend (v) 92 (msv (make-array 1024)) 93 (class-id->metaclass-id (make-array 1024 :initial-element nil))) 94 95 (flet ((grow-vectors () 96 (let* ((old-size class-table-size) 97 (new-size (* 2 old-size))) 98 (declare (fixnum old-size new-size)) 99 (macrolet ((extend (v) 102 100 `(setq ,v (%extend-vector old-size ,v new-size)))) 103 101 (extend c) … … 105 103 (extend cw) 106 104 (extend mw) 105 (fill cw nil :start old-size :end new-size) 106 (fill mw nil :start old-size :end new-size) 107 107 (extend csv) 108 (extend msv)) 109 (setq class-table-size new-size))) 110 id))) 111 (defun id->objc-class (i) 112 (svref c i)) 113 (defun (setf id->objc-class) (new i) 114 (setf (svref c i) new)) 115 (defun id->objc-metaclass (i) 116 (svref m i)) 117 (defun (setf id->objc-metaclass) (new i) 118 (setf (svref m i) new)) 119 (defun id->objc-class-wrapper (i) 120 (svref cw i)) 121 (defun (setf id->objc-class-wrapper) (new i) 122 (setf (svref cw i) new)) 123 (defun id->objc-metaclass-wrapper (i) 124 (svref mw i)) 125 (defun (setf id->objc-metaclass-wrapper) (new i) 126 (setf (svref mw i) new)) 127 (defun id->objc-class-slots-vector (i) 128 (svref csv i)) 129 (defun (setf id->objc-class-slots-vector) (new i) 130 (setf (svref csv i) new)) 131 (defun id->objc-metaclass-slots-vector (i) 132 (svref msv i)) 133 (defun (setf id->objc-metaclass-slots-vector) (new i) 134 (setf (svref msv i) new)) 135 136 (defun %clear-objc-class-maps () 137 (with-lock-grabbed (objc-class-lock) 138 (fill c 0) 139 (fill m 0) 140 (fill cw 0) 141 (fill mw 0) 142 (fill csv 0) 143 (fill msv 0) 144 (setf (splay-tree-root objc-class-map) nil 145 (splay-tree-root objc-metaclass-map) nil 146 (splay-tree-count objc-class-map) 0 147 (splay-tree-count objc-metaclass-map) 0 148 next-objc-class-id 0))) 149 150 (defun register-objc-class (class) 151 "ensure that the class (and metaclass) are mapped to a small integer, 152 and that each have slots-vectors associated with them." 153 (with-lock-grabbed (objc-class-lock) 154 (ensure-objc-classptr-resolved class) 155 (or (splay-tree-get objc-class-map class) 156 (let* ((id (assign-next-class-id)) 157 (class (%inc-ptr class 0)) 158 (meta (pref class #+apple-objc :objc_class.isa #+gnu-objc :objc_class.class_pointer))) 159 (splay-tree-put objc-class-map class id) 160 (splay-tree-put objc-metaclass-map meta id) 161 (setf (svref c id) class 162 (svref m id) meta 163 (svref csv id) 164 (make-objc-class-slots-vector class) 165 (svref msv id) 166 (make-objc-metaclass-slots-vector meta)) 167 id)))) 168 (defun objc-class-id (class) 169 (with-lock-grabbed (objc-class-lock) 170 (splay-tree-get objc-class-map class))) 171 (defun objc-metaclass-id (meta) 172 (with-lock-grabbed (objc-class-lock) 173 (splay-tree-get objc-metaclass-map meta))) 174 (defun objc-class-map () objc-class-map) 175 (defun objc-metaclass-map () objc-metaclass-map))) 108 (extend msv) 109 (extend class-id->metaclass-id) 110 (fill class-id->metaclass-id nil :start old-size :end new-size)) 111 (setq class-table-size new-size)))) 112 (flet ((assign-next-class-id () 113 (let* ((id next-objc-class-id)) 114 (if (= (incf next-objc-class-id) class-table-size) 115 (grow-vectors)) 116 id)) 117 (assign-next-metaclass-id () 118 (let* ((id next-objc-metaclass-id)) 119 (if (= (incf next-objc-metaclass-id) class-table-size) 120 (grow-vectors)) 121 id))) 122 (defun id->objc-class (i) 123 (svref c i)) 124 (defun (setf id->objc-class) (new i) 125 (setf (svref c i) new)) 126 (defun id->objc-metaclass (i) 127 (svref m i)) 128 (defun (setf id->objc-metaclass) (new i) 129 (setf (svref m i) new)) 130 (defun id->objc-class-wrapper (i) 131 (svref cw i)) 132 (defun (setf id->objc-class-wrapper) (new i) 133 (setf (svref cw i) new)) 134 (defun id->objc-metaclass-wrapper (i) 135 (svref mw i)) 136 (defun (setf id->objc-metaclass-wrapper) (new i) 137 (setf (svref mw i) new)) 138 (defun id->objc-class-slots-vector (i) 139 (svref csv i)) 140 (defun (setf id->objc-class-slots-vector) (new i) 141 (setf (svref csv i) new)) 142 (defun id->objc-metaclass-slots-vector (i) 143 (svref msv i)) 144 (defun (setf id->objc-metaclass-slots-vector) (new i) 145 (setf (svref msv i) new)) 146 (defun %clear-objc-class-maps () 147 (with-lock-grabbed (objc-class-lock) 148 (fill c 0) 149 (fill m 0) 150 (fill cw nil) 151 (fill mw nil) 152 (fill csv 0) 153 (fill msv 0) 154 (fill class-id->metaclass-id nil) 155 (setf (splay-tree-root objc-class-map) nil 156 (splay-tree-root objc-metaclass-map) nil 157 (splay-tree-count objc-class-map) 0 158 (splay-tree-count objc-metaclass-map) 0 159 next-objc-class-id 0 160 next-objc-metaclass-id 0))) 161 (flet ((install-objc-metaclass (meta) 162 (or (splay-tree-get objc-metaclass-map meta) 163 (let* ((id (assign-next-metaclass-id)) 164 (meta (%inc-ptr meta 0))) 165 (splay-tree-put objc-metaclass-map meta id) 166 (setf (svref m id) meta 167 (svref msv id) 168 (make-objc-metaclass-slots-vector meta)) 169 id)))) 170 (defun register-objc-class (class) 171 "ensure that the class is mapped to a small integer and associate a slots-vector with it." 172 (with-lock-grabbed (objc-class-lock) 173 (ensure-objc-classptr-resolved class) 174 (or (splay-tree-get objc-class-map class) 175 (let* ((id (assign-next-class-id)) 176 (class (%inc-ptr class 0)) 177 (meta (pref class #+apple-objc :objc_class.isa #+gnu-objc :objc_class.class_pointer))) 178 (splay-tree-put objc-class-map class id) 179 (setf (svref c id) class 180 (svref csv id) 181 (make-objc-class-slots-vector class) 182 (svref class-id->metaclass-id id) 183 (install-objc-metaclass meta)) 184 id))))) 185 (defun objc-class-id (class) 186 (with-lock-grabbed (objc-class-lock) 187 (splay-tree-get objc-class-map class))) 188 (defun objc-metaclass-id (meta) 189 (with-lock-grabbed (objc-class-lock) 190 (splay-tree-get objc-metaclass-map meta))) 191 (defun objc-class-id->objc-metaclass-id (class-id) 192 (svref class-id->metaclass-id class-id)) 193 (defun objc-class-id->objc-metaclass (class-id) 194 (svref m (svref class-id->metaclass-id class-id))) 195 (defun objc-class-map () objc-class-map) 196 (defun objc-metaclass-map () objc-metaclass-map)))) 176 197 177 198 (pushnew #'%clear-objc-class-maps *save-exit-functions* :test #'eq … … 235 256 (pushnew 'remap-all-library-classes *lisp-system-pointer-functions*) 236 257 258 (let* ((cfstring-sections (cons 0 nil))) 259 (defun reset-cfstring-sections () 260 (rplaca cfstring-sections 0) 261 (rplacd cfstring-sections nil)) 262 (defun find-cfstring-sections () 263 (let* ((image-count (#_ _dyld_image_count))) 264 (when (> image-count (car cfstring-sections)) 265 (process-section-in-all-libraries 266 #$SEG_DATA 267 "__cfstring" 268 #'(lambda (sectaddr size) 269 (let* ((addr (%ptr-to-int sectaddr)) 270 (limit (+ addr size)) 271 (already (member addr (cdr cfstring-sections) :key #'car))) 272 (if already 273 (rplacd already limit) 274 (push (cons addr limit) (cdr cfstring-sections)))))) 275 (setf (car cfstring-sections) image-count)))) 276 (defun pointer-in-cfstring-section-p (ptr) 277 (let* ((addr (%ptr-to-int ptr))) 278 (dolist (s (cdr cfstring-sections)) 279 (when (and (>= addr (car s)) 280 (< addr (cdr s))) 281 (return t)))))) 282 283 284 237 285 ) 238 286 … … 298 346 (pref class :objc_class.name)) 299 347 "NS")) 300 (meta (id->objc-metaclass id)) 301 (meta-name (intern (concatenate 'string 302 "+" 303 (string class-name)) 304 "NS")) 305 (meta-super (pref meta :objc_class.super_class))) 306 ;; It's important (here and when initializing the class 307 ;; below) to use the "canonical" (registered) version 308 ;; of the class, since some things in CLOS assume 309 ;; EQness. We probably don't want to violate that 310 ;; assumption; it'll be easier to revive a saved image 311 ;; if we don't have a lot of EQL-but-not-EQ class pointers 312 ;; to deal with. 313 (initialize-instance meta 314 :name meta-name 315 :direct-superclasses 316 (list 317 (if (or (%null-ptr-p meta-super) 318 (not (%objc-metaclass-p meta-super))) 319 (find-class 'objc:objc-class) 320 (canonicalize-registered-metaclass meta-super))) 321 :peer class 322 :foreign t) 323 (setf (find-class meta-name) meta) 324 ; (setf (id->objc-metaclass-wrapper id) (%class-own-wrapper meta)) 348 (meta-id (objc-class-id->objc-metaclass-id id)) 349 (meta (id->objc-metaclass meta-id))) 350 ;; Metaclass may already be initialized. It'll have a class 351 ;; wrapper if so. 352 (unless (id->objc-metaclass-wrapper meta-id) 353 (let* ((meta-name (intern 354 (concatenate 'string 355 "+" 356 (string 357 (objc-to-lisp-classname 358 (%get-cstring 359 (pref meta :objc_class.name)) 360 "NS"))) 361 "NS")) 362 (meta-super (pref meta :objc_class.super_class))) 363 ;; It's important (here and when initializing the class 364 ;; below) to use the "canonical" (registered) version 365 ;; of the class, since some things in CLOS assume 366 ;; EQness. We probably don't want to violate that 367 ;; assumption; it'll be easier to revive a saved image 368 ;; if we don't have a lot of EQL-but-not-EQ class pointers 369 ;; to deal with. 370 (initialize-instance meta 371 :name meta-name 372 :direct-superclasses 373 (list 374 (if (or (%null-ptr-p meta-super) 375 (not (%objc-metaclass-p meta-super))) 376 (find-class 'objc:objc-class) 377 (canonicalize-registered-metaclass meta-super))) 378 :peer class 379 :foreign t) 380 (setf (find-class meta-name) meta))) 325 381 (setf (slot-value class 'direct-slots) 326 382 (%compute-foreign-direct-slots class)) … … 334 390 :peer meta 335 391 :foreign t) 336 ; (setf (id->objc-class-wrapper id) (%class-own-wrapper class))337 392 (setf (find-class class-name) class)))))) 338 393 … … 919 974 #+gnu-objc #$_CLS_META)) 920 975 976 (defun %objc-class-posing-p (class) 977 (logtest (pref class :objc_class.info) 978 #+apple-objc #$CLS_POSING 979 #+gnu-objc #$_CLS_POSING)) 921 980 922 981 … … 942 1001 (%null-ptr) 943 1002 0))) 944 (meta ( id->objc-metaclass id))1003 (meta (objc-class-id->objc-metaclass id)) 945 1004 (class (id->objc-class id)) 946 1005 (meta-name (intern (format nil "+~a" class-name) … … 951 1010 :name meta-name 952 1011 :direct-superclasses (list meta-super)) 953 (setf ;(id->objc-metaclass-wrapper id) (%class-own-wrapper meta) 954 (find-class meta-name) meta) 1012 (setf (find-class meta-name) meta) 955 1013 class))) 956 1014 … … 1029 1087 (defun %objc-instance-class-index (p) 1030 1088 #+apple-objc 1031 (let* ((instance-apparent-size (zone-pointer-size p))) 1032 (when (and instance-apparent-size (not (eql instance-apparent-size 0))) 1033 (locally (declare (fixnum instance-apparent-size)) 1034 (with-macptrs ((parent (pref p :objc_object.isa))) 1035 (let* ((idx (objc-class-id parent))) 1036 (when idx 1037 (let* ((parent-size (if idx (pref parent :objc_class.instance_size)))) 1038 (if (eql (- (ash (ash (the fixnum (+ parent-size 17)) -4) 4) 2) 1039 instance-apparent-size) 1040 idx))))))))) 1089 (if (or (pointer-in-cfstring-section-p p) 1090 (with-macptrs ((zone (#_malloc_zone_from_ptr p))) 1091 (not (%null-ptr-p zone)))) 1092 (with-macptrs ((parent (pref p :objc_object.isa))) 1093 (objc-class-id parent))) 1041 1094 #+gnu-objc 1042 1095 (with-macptrs ((parent (pref p objc_object.class_pointer))) 1043 1096 (objc-class-id-parent)) 1097 ) 1044 1098 1045 1099 ;;; If an instance, return (values :INSTANCE <class>). … … 1365 1419 (free obj))) 1366 1420 1421 #+threads-problem 1367 1422 (def-ccl-pointers install-deallocate-hook () 1368 1423 (setf (%get-ptr (foreign-symbol-address "__dealloc")) deallocate-nsobject)) … … 1393 1448 ") 1394 1449 1450 1451 (defun retain-objc-instance (instance) 1452 (objc-message-send instance "retain")) 1395 1453 1396 1454 ;;; Execute BODY with an autorelease pool
Note:
See TracChangeset
for help on using the changeset viewer.
