Changeset 5728


Ignore:
Timestamp:
Jan 18, 2007, 3:10:33 AM (18 years ago)
Author:
Gary Byers
Message:

More ObjC 2.0, ppc64 changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/examples/objc-runtime.lisp

    r5696 r5728  
    4545  (progn
    4646    (use-interface-dir :cocoa)
    47     #-apple-objc-2.0
    4847    (use-interface-dir :carbon))        ; need :carbon for things in this file
    4948  #+gnu-objc
     
    6261(defloadvar *NSApp* nil )
    6362
     63;;; Apple ObjC 2.0 provides (#_objc_getProtocol name).  In other
     64;;; runtimes, there doesn't seem to be any way to find a Protocol
     65;;; object given its name.  We need to be able to ask at runtime
     66;;; whether a given object conforms to a protocol in order to
     67;;; know when a protocol method is ambiguous, at least when the
     68;;; message contains ambiguous methods and some methods are protocol
     69;;; methods
     70(defloadvar *objc-protocols* (make-hash-table :test #'equal))
     71
     72(defun lookup-objc-protocol (name)
     73  (values (gethash name *objc-protocols*)))
    6474
    6575(defun ensure-objc-classptr-resolved (classptr)
     
    6878  (unless (logtest #$_CLS_RESOLV (pref classptr :objc_class.info))
    6979    (external-call "__objc_resolve_class_links" :void)))
     80
    7081
    7182
     
    451462#|(defconstant JMP-ctr #x5c "count register jmp_buf offset")|#
    452463(defconstant JMP-sp 0 "stack pointer offset in jmp_buf")
    453 (defconstant JMP-r13 8 "offset of r13 (which we clobber) in jmp_buf")
    454 (defconstant JMP-r14 12 "offset of r14 (which we also clobber) in jmp_buf"))
     464(defconstant JMP-r14 12 "offset of r14 (which we clobber) in jmp_buf")
     465(defconstant JMP-r15 16 "offset of r14 (which we also clobber) in jmp_buf"))
    455466
    456467#+ppc64-target
     
    459470#|(defconstant JMP-ctr #x5c "count register jmp_buf offset")|#
    460471(defconstant JMP-sp 0 "stack pointer offset in jmp_buf")
    461 (defconstant JMP-r13 #x10 "offset of r13 (which we clobber) in jmp_buf")
    462 (defconstant JMP-r14 #x18 "offset of r14 (which we also clobber) in jmp_buf"))
     472(defconstant JMP-r13 #x10 "offset of r13 (which we preserve) in jmp_buf")
     473(defconstant JMP-r14 #x18 "offset of r14 (which we clobber) in jmp_buf")
     474(defconstant JMP-r15 #x20 "offset of r15 (which we also clobber) in jmp_buf"))
    463475 
    464476
    465 ;;; A malloc'ed pointer to two words of machine code.  The first
    466 ;;; instruction (rather obviously) copies r13 to r4.  A C function
    467 ;;; passes its second argument in r4, but since r4 isn't saved in a
    468 ;;; jmp_buf, we have to do this copy.  The second instruction just
    469 ;;; jumps to the address in the count register, which is where we
    470 ;;; really wanted to go in the first place.
     477;;; A malloc'ed pointer to thre words of machine code.  The first
     478;;; instruction copies the address of the trampoline callback from r14
     479;;; to the count register.  The second instruction (rather obviously)
     480;;; copies r15 to r4.  A C function passes its second argument in r4,
     481;;; but since r4 isn't saved in a jmp_buf, we have to do this copy.
     482;;; The second instruction just jumps to the address in the count
     483;;; register, which is where we really wanted to go in the first
     484;;; place.
    471485
    472486(macrolet ((ppc-lap-word (instruction-form)
     
    475489                                      (ppc-lap-function () ((?? 0))
    476490                                       ,instruction-form)))
    477                            0) 0)))
     491                           0) #+ppc64-target 1 #+ppc32-target 0)))
    478492  (defloadvar *setjmp-catch-lr-code*
    479493      (let* ((p (malloc 12)))
    480494        (setf (%get-unsigned-long p 0) (ppc-lap-word (mtctr 14))
    481               (%get-unsigned-long p 4) (ppc-lap-word (mr 4 13))
     495              (%get-unsigned-long p 4) (ppc-lap-word (mr 4 15))
    482496              (%get-unsigned-long p 8) (ppc-lap-word (bctr)))
    483497        ;;; Force this code out of the data cache and into memory, so
     
    499513;;; wind up calling THROW-TO-CATCH-FRAME with the specified catch
    500514;;; frame as its second argument.  The C frame used here is just
    501 ;; an empty C stack frame from which the callback will be called.
     515;;; an empty C stack frame from which the callback will be called.
    502516
    503517(defun %associate-jmp-buf-with-catch-frame (jmp-buf catch-frame c-frame)
    504518  (%set-object jmp-buf JMP-sp c-frame)
    505   (%set-object jmp-buf JMP-r13 catch-frame)
     519  (%set-object jmp-buf JMP-r15 catch-frame)
     520  #+ppc64-target
     521  (%set-object jmp-buf JMP-r13 (%get-os-context))
    506522  (setf (%get-ptr jmp-buf JMP-lr) *setjmp-catch-lr-code*
    507523        (%get-ptr jmp-buf JMP-r14) throw-to-catch-frame)
     
    565581                 (meta-id (objc-class-id->objc-metaclass-id i))
    566582                 (m (id->objc-metaclass meta-id)))
     583            (let* ((class (make-objc-class-pair super (make-cstring (objc-class-id-foreign-name i))))
     584                   (meta (pref class #+apple-objc :objc_class.isa
     585                               #+gnu-objc :objc-class.class_pointer)))
    567586            (unless (splay-tree-get metaclass-map m)
    568587              (%revive-macptr m)
    569               (%setf-macptr m (%make-basic-meta-class
    570                                (make-cstring (objc-metaclass-id-foreign-name meta-id))
    571                                super
    572                                (find-class 'ns::ns-object)))
     588              (%setf-macptr m meta)
    573589              (splay-tree-put metaclass-map m meta-id))
    574             (%setf-macptr c (%make-class-object
    575                              m
    576                              super
    577                              (make-cstring (objc-class-id-foreign-name i))
    578                              (%null-ptr)
    579                              0))
    580 
     590            (%setf-macptr c class))
     591            #+apple-objc-2.0
     592            (%add-objc-class c)
     593            #-apple-objc-2.0
    581594            (multiple-value-bind (ivars instance-size)
    582595                (%make-objc-ivars c)
     
    12261239          (%get-signed-long method-vector 12) -1)
    12271240    method-vector))
    1228  
     1241
    12291242
    12301243;;; Make a meta-class object (with no instance variables or class
     
    14071420    (#___objc_exec_class m)))
    14081421
     1422#+apple-objc-2.0
     1423(defun %add-objc-class (class)
     1424  (#_objc_registerClassPair class))
    14091425
    14101426(defun %make-nsstring (string)
     
    14351451
    14361452
    1437 #+apple-objc
    1438 (defun zone-pointer-size (p)
    1439   (with-macptrs ((zone (#_malloc_zone_from_ptr p)))
    1440     (unless (%null-ptr-p zone)
    1441       (let* ((size (ff-call (pref zone :malloc_zone_t.size)
    1442                             :address zone
    1443                             :address p
    1444                             :int)))
    1445         (declare (fixnum size))
    1446         (unless (zerop size)
    1447           size)))))
     1453
    14481454
    14491455(defun objc-private-class-id (classptr)
     
    14511457    (when info
    14521458      (or (private-objc-class-info-declared-ancestor info)
    1453           (with-macptrs ((super (pref classptr :objc_class.super_class)))
     1459          (with-macptrs ((super #+apple-objc-2.0 (#_class_getSuperclass classptr)
     1460                                #-apple-objc-2.0 (pref classptr :objc_class.super_class)))
    14541461            (loop
    14551462              (when (%null-ptr-p super)
     
    14591466                  (return (setf (private-objc-class-info-declared-ancestor info)
    14601467                                id))
    1461                   (%setf-macptr super (pref super :objc_class.super_class))))))))))
     1468                  (%setf-macptr super #+apple-objc-2.0 (#_class_getSuperclass super)
     1469                                #-apple-objc-2.0 (pref super :objc_class.super_class))))))))))
    14621470
    14631471(defun objc-class-or-private-class-id (classptr)
     
    14671475
    14681476(defun %objc-instance-class-index (p)
    1469   (if (with-macptrs (q)
    1470         (safe-get-ptr p q)
    1471         (not (%null-ptr-p q)))
    1472     (with-macptrs ((parent #+apple-objc (pref p :objc_object.isa)
    1473                            #+gnu-objc (pref p :objc_object.class_pointer)))
    1474       (or
    1475        (objc-class-id parent)
    1476        (objc-private-class-id parent)))))
     1477  (unless (%null-ptr-p p)
     1478    (if (with-macptrs (q)
     1479          (safe-get-ptr p q)
     1480          (not (%null-ptr-p q)))
     1481      (with-macptrs ((parent #+apple-objc (pref p :objc_object.isa)
     1482                             #+gnu-objc (pref p :objc_object.class_pointer)))
     1483        (or
     1484         (objc-class-id parent)
     1485         (objc-private-class-id parent))))))
    14771486
    14781487
     
    15351544
    15361545(defun %add-objc-method (classptr selector typestring imp)
    1537   #+apple-objc
    1538   (#_class_addMethods classptr
    1539                       (%mlist-containing classptr selector typestring imp))
    1540   #+gnu-objc
     1546  #+apple-objc-2.0
     1547  (with-cstrs ((typestring typestring))
     1548    (or (not (eql #$NO (#_class_addMethod classptr selector imp typestring)))
     1549        (let* ((m (if (objc-metaclass-p classptr)
     1550                    (#_class_getClassMethod classptr selector)
     1551                    (#_class_getInstanceMethod classptr selector))))
     1552          (if (not (%null-ptr-p m))
     1553            (#_method_setImplementation m imp)
     1554            (error "Can't add ~s method to class ~s" selector typestring)))))
     1555  #-apple-objc-2.0
     1556  (progn
     1557    #+apple-objc
     1558    (#_class_addMethods classptr
     1559                        (%mlist-containing classptr selector typestring imp))
     1560    #+gnu-objc
    15411561  ;;; We have to do this ourselves, and have to do it with the runtime
    15421562  ;;; mutex held.
    1543   (with-gnu-objc-mutex-locked (*gnu-objc-runtime-mutex*)
    1544     (let* ((ctypestring (make-cstring typestring))
    1545            (new-mlist nil))
    1546       (with-macptrs ((method (external-call "search_for_method_in_list"
    1547                               :address (pref classptr :objc_class.methods)
    1548                               :address selector
    1549                               :address)))
    1550         (when (%null-ptr-p method)
    1551           (setq new-mlist (make-record :objc_method_list :method_count 1))
    1552           (%setf-macptr method (pref new-mlist :objc_method_list.method_list)))
    1553         (setf (pref method :objc_method.method_name) selector
    1554               (pref method :objc_method.method_types) ctypestring
    1555               (pref method :objc_method.method_imp) imp)
    1556         (if new-mlist
    1557           (external-call "GSObjCAddMethods"
    1558                         :address classptr
    1559                         :address new-mlist
    1560                         :void)
    1561           (external-call "__objc_update_dispatch_table_for_class"
    1562                         :address classptr
    1563                          :void))))))
     1563    (with-gnu-objc-mutex-locked (*gnu-objc-runtime-mutex*)
     1564      (let* ((ctypestring (make-cstring typestring))
     1565             (new-mlist nil))
     1566        (with-macptrs ((method (external-call "search_for_method_in_list"
     1567                                              :address (pref classptr :objc_class.methods)
     1568                                              :address selector
     1569                                              :address)))
     1570          (when (%null-ptr-p method)
     1571            (setq new-mlist (make-record :objc_method_list :method_count 1))
     1572            (%setf-macptr method (pref new-mlist :objc_method_list.method_list)))
     1573          (setf (pref method :objc_method.method_name) selector
     1574                (pref method :objc_method.method_types) ctypestring
     1575                (pref method :objc_method.method_imp) imp)
     1576          (if new-mlist
     1577            (external-call "GSObjCAddMethods"
     1578                          :address classptr
     1579                          :address new-mlist
     1580                          :void)
     1581            (external-call "__objc_update_dispatch_table_for_class"
     1582                          :address classptr
     1583                           :void)))))))
    15641584
    15651585(defvar *lisp-objc-methods* (make-hash-table :test #'eq))
     
    17581778              (rlet ((,super :objc_super
    17591779                       #+apple-objc :receiver #+gnu-objc :self ,self
    1760                        :class
     1780                       #+apple-objc-2.0 :super_class #-apple-objc-2.0 :class
    17611781                       ,@(if class-p
     1782                             #+apple-objc-2.0
     1783                             `((external-call "_class_getSuperclass"
     1784                                :address (pref (@class ,class-name) :objc_class.isa) :address))
     1785                             #-apple-objc-2.0
    17621786                             `((pref
    17631787                                (pref (@class ,class-name)
     
    17651789                                 #+gnu-objc :objc_class.super_class )
    17661790                                :objc_class.super_class))
     1791                             #+apple-objc-2.0
     1792                             `((external-call "_class_getSuperclass"
     1793                                :address (@class ,class-name) :address))
     1794                             #-apple-objc-2.0
    17671795                             `((pref (@class ,class-name) :objc_class.super_class)))))
    17681796                (macrolet ((send-super (msg &rest args &environment env)
     
    17931821
    17941822(defun class-get-instance-method (class sel)
    1795   #+apple-objc (let* ((p (#_class_getInstanceMethod class sel)))
    1796                  (if (%null-ptr-p p)                   
    1797                    (unless (logtest #$CLS_INITIALIZED (pref (pref class :objc_class.isa)  :objc_class.info))
    1798                      ;; Do this for effect; ignore the :<IMP> it returns.
    1799                      ;; (It should cause the CLS_NEED_BIND flag to turn itself
    1800                      ;; off after the class has been initialized; we need
    1801                      ;; the class and all superclasses to have been initialized,
    1802                      ;; so that we can find category methods via
    1803                      ;; #_class_getInstanceMethod.
    1804                      (external-call "_class_lookupMethod"
    1805                                     :id class
    1806                                     :<SEL> sel
    1807                                     :address)
    1808                      (%setf-macptr p (#_class_getInstanceMethod class sel))))
    1809                  p)
     1823  #+apple-objc (#_class_getInstanceMethod class sel)
    18101824  #+gnu-objc (#_class_get_instance_method class sel))
    18111825
     
    18421856         :key #'function-name)
    18431857)
    1844 
    1845 ;;; Return a typestring and offset as multiple values.
    1846 
    1847 (defun objc-get-method-argument-info (m i)
    1848   #+apple-objc
    1849   (%stack-block ((type 4) (offset 4))
    1850     (#_method_getArgumentInfo m i type offset)
    1851     (values (%get-cstring (%get-ptr type)) (%get-signed-long offset)))
    1852   #+gnu-objc
    1853   (progn
    1854     (with-macptrs ((typespec (#_objc_skip_argspec (pref m :objc_method.method_types))))
    1855       (dotimes (j i (values (%get-cstring typespec)
    1856                             (#_strtol (#_objc_skip_typespec typespec)
    1857                                       (%null-ptr)
    1858                                       10.)))
    1859         (%setf-macptr typespec (#_objc_skip_argspec typespec))))))
    18601858
    18611859 
     
    18931891      (%get-cstring cstring))))
    18941892
     1893#+apple-objc-2.0
     1894;;; This isn't defined in headers; it's sort of considered a built-in
     1895;;; type by the ObjC frontend.  (See also the ObjC runtime source.)
     1896(eval-when (:compile_toplevel :execute)
     1897  (def-foreign-type nil
     1898      (:struct :_objc_exception_data
     1899        (:buf :jmp_buf)
     1900        (:pointers (:array :address 4)))))
     1901
     1902;;; Apple's mechanism for maintaining per-thread exception handler
     1903;;; state isn't thread safe, which suggests that we should probably
     1904;;; install our own callbacks via #_objc_exception_set_functions.
     1905;;; It's 2007.
     1906
     1907#+apple-objc-2.0
     1908(defmacro with-ns-exceptions-as-errors (&body body)
     1909  (let* ((data (gensym))
     1910         (cframe (gensym)))
     1911    `(rletZ ((,data :_objc_exception_data))
     1912      (unwind-protect
     1913           (progn
     1914             (#_objc_exception_try_enter ,data)
     1915               (catch ,data
     1916               (with-c-frame ,cframe
     1917                 (%associate-jmp-buf-with-catch-frame
     1918                  ,data
     1919                  (%fixnum-ref (%current-tcr) target::tcr.catch-top)
     1920                  ,cframe)
     1921                 (progn
     1922                   ,@body))))
     1923        (check-ns-exception ,data)))))
     1924                 
     1925             
     1926   
     1927#-apple-objc-2.0
    18951928(defmacro with-ns-exceptions-as-errors (&body body)
    18961929  #+apple-objc
     
    19141947  )
    19151948
    1916 #+apple-objc
     1949#+apple-objc-2.0
     1950(defun check-ns-exception (data)
     1951  (with-macptrs ((exception (#_objc_exception_extract data)))
     1952    (if (%null-ptr-p exception)
     1953      (#_objc_exception_try_exit data)
     1954      (error (ns-exception->lisp-condition (%inc-ptr exception 0))))))
     1955
     1956#+(and apple-objc (not apple-objc-2.0))
    19171957(defun check-ns-exception (nshandler)
    19181958  (with-macptrs ((exception (external-call "__NSExceptionObjectFromHandler2"
Note: See TracChangeset for help on using the changeset viewer.