0.6.7.22: removed CVS dollar-Header-dollar tags from sources
[sbcl.git] / src / pcl / env.lisp
1 ;;;; basic environmental stuff
2
3 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; more information.
5
6 ;;;; This software is derived from software originally released by Xerox
7 ;;;; Corporation. Copyright and release statements follow. Later modifications
8 ;;;; to the software are in the public domain and are provided with
9 ;;;; absolutely no warranty. See the COPYING and CREDITS files for more
10 ;;;; information.
11
12 ;;;; copyright information from original PCL sources:
13 ;;;;
14 ;;;; Copyright (c) 1985, 1986, 1987, 1988, 1989, 1990 Xerox Corporation.
15 ;;;; All rights reserved.
16 ;;;;
17 ;;;; Use and copying of this software and preparation of derivative works based
18 ;;;; upon this software are permitted. Any distribution of this software or
19 ;;;; derivative works must comply with all applicable United States export
20 ;;;; control laws.
21 ;;;;
22 ;;;; This software is made available AS IS, and Xerox Corporation makes no
23 ;;;; warranty about the software, its performance or its conformity to any
24 ;;;; specification.
25
26 (in-package "SB-PCL")
27 \f
28 ;;; FIXME: This stuff isn't part of the ANSI spec, and isn't even
29 ;;; exported from PCL, but it looks as though it might be useful,
30 ;;; so I don't want to just delete it. Perhaps it should go in
31 ;;; a contrib/ directory eventually?
32
33 #|
34 ;;; TRACE-METHOD and UNTRACE-METHOD accept method specs as arguments. A
35 ;;; method-spec should be a list like:
36 ;;;   (<generic-function-spec> qualifiers* (specializers*))
37 ;;; where <generic-function-spec> should be either a symbol or a list
38 ;;; of (SETF <symbol>).
39 ;;;
40 ;;;   For example, to trace the method defined by:
41 ;;;
42 ;;;     (defmethod foo ((x spaceship)) 'ss)
43 ;;;
44 ;;;   You should say:
45 ;;;
46 ;;;     (trace-method '(foo (spaceship)))
47 ;;;
48 ;;;   You can also provide a method object in the place of the method
49 ;;;   spec, in which case that method object will be traced.
50 ;;;
51 ;;; For untrace-method, if an argument is given, that method is untraced.
52 ;;; If no argument is given, all traced methods are untraced.
53 (defclass traced-method (method)
54      ((method :initarg :method)
55       (function :initarg :function
56                 :reader method-function)
57       (generic-function :initform nil
58                         :accessor method-generic-function)))
59
60 (defmethod method-lambda-list ((m traced-method))
61   (with-slots (method) m (method-lambda-list method)))
62
63 (defmethod method-specializers ((m traced-method))
64   (with-slots (method) m (method-specializers method)))
65
66 (defmethod method-qualifiers ((m traced-method))
67   (with-slots (method) m (method-qualifiers method)))
68
69 (defmethod accessor-method-slot-name ((m traced-method))
70   (with-slots (method) m (accessor-method-slot-name method)))
71
72 (defvar *traced-methods* ())
73
74 (defun trace-method (spec &rest options)
75   (multiple-value-bind (gf omethod name)
76       (parse-method-or-spec spec)
77     (let* ((tfunction (trace-method-internal (method-function omethod)
78                                              name
79                                              options))
80            (tmethod (make-instance 'traced-method
81                                    :method omethod
82                                    :function tfunction)))
83       (remove-method gf omethod)
84       (add-method gf tmethod)
85       (pushnew tmethod *traced-methods*)
86       tmethod)))
87
88 (defun untrace-method (&optional spec)
89   (flet ((untrace-1 (m)
90            (let ((gf (method-generic-function m)))
91              (when gf
92                (remove-method gf m)
93                (add-method gf (slot-value m 'method))
94                (setq *traced-methods* (remove m *traced-methods*))))))
95     (if (not (null spec))
96         (multiple-value-bind (gf method)
97             (parse-method-or-spec spec)
98           (declare (ignore gf))
99           (if (memq method *traced-methods*)
100               (untrace-1 method)
101               (error "~S is not a traced method?" method)))
102         (dolist (m *traced-methods*) (untrace-1 m)))))
103
104 (defun trace-method-internal (ofunction name options)
105   (eval `(untrace ,name))
106   (setf (symbol-function name) ofunction)
107   (eval `(trace ,name ,@options))
108   (symbol-function name))
109 |#
110 \f
111 ;(defun compile-method (spec)
112 ;  (multiple-value-bind (gf method name)
113 ;      (parse-method-or-spec spec)
114 ;    (declare (ignore gf))
115 ;    (compile name (method-function method))
116 ;    (setf (method-function method) (symbol-function name))))
117
118 ;;; not used in SBCL
119 #|
120 (defmacro undefmethod (&rest args)
121   (declare (arglist name {method-qualifier}* specializers))
122   `(undefmethod-1 ',args))
123
124 (defun undefmethod-1 (args)
125   (multiple-value-bind (gf method)
126       (parse-method-or-spec args)
127     (when (and gf method)
128       (remove-method gf method)
129       method)))
130 |#
131
132 ;;; FIXME: Delete these.
133 #|
134 (pushnew :pcl *features*)
135 (pushnew :portable-commonloops *features*)
136 (pushnew :pcl-structures *features*)
137 |#
138
139 ;;; FIXME: This was for some unclean bootstrapping thing we don't
140 ;;; need in SBCL, right? So we can delete it, right?
141 ;;; #+cmu
142 ;;; (when (find-package "OLD-PCL")
143 ;;;   (setf (symbol-function (find-symbol "PRINT-OBJECT" :old-pcl))
144 ;;;     (symbol-function 'sb-pcl::print-object)))
145 \f
146 ;;;; MAKE-LOAD-FORM
147
148 ;; Overwrite the old bootstrap non-generic MAKE-LOAD-FORM function with a
149 ;; shiny new generic function.
150 (fmakunbound 'make-load-form)
151 (defgeneric make-load-form (object &optional environment))
152
153 ;; Link bootstrap-time how-to-dump-it information into the shiny new
154 ;; CLOS system.
155 (defmethod make-load-form ((obj sb-sys:structure!object)
156                            &optional (env nil env-p))
157   (if env-p
158       (sb-sys:structure!object-make-load-form obj env)
159       (sb-sys:structure!object-make-load-form obj)))
160
161 (defmethod make-load-form ((object wrapper) &optional env)
162   (declare (ignore env))
163   (let ((pname (sb-kernel:class-proper-name (sb-kernel:layout-class object))))
164     (unless pname
165       (error "can't dump wrapper for anonymous class:~%  ~S"
166              (sb-kernel:layout-class object)))
167     `(sb-kernel:class-layout (cl:find-class ',pname))))
168 \f
169 ;;;; The following are hacks to deal with CMU CL having two different CLASS
170 ;;;; classes.
171
172 (defun coerce-to-pcl-class (class)
173   (if (typep class 'cl:class)
174       (or (sb-kernel:class-pcl-class class)
175           (find-structure-class (cl:class-name class)))
176       class))
177
178 (defmethod make-instance ((class cl:class) &rest stuff)
179   (apply #'make-instance (coerce-to-pcl-class class) stuff))
180 (defmethod change-class (instance (class cl:class))
181   (apply #'change-class instance (coerce-to-pcl-class class)))
182
183 (macrolet ((frob (&rest names)
184              `(progn
185                 ,@(mapcar #'(lambda (name)
186                               `(defmethod ,name ((class cl:class))
187                                  (funcall #',name
188                                           (coerce-to-pcl-class class))))
189                           names))))
190   (frob
191     class-direct-slots
192     class-prototype
193     class-precedence-list
194     class-direct-default-initargs
195     class-direct-superclasses
196     compute-class-precedence-list
197     class-default-initargs class-finalized-p
198     class-direct-subclasses class-slots
199     make-instances-obsolete))