-
Notifications
You must be signed in to change notification settings - Fork 146
/
Copy pathbuiltin.lisp
156 lines (131 loc) · 6.44 KB
/
builtin.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
;;;; -*- Mode: Lisp; Syntax: Common-Lisp; Package: CLOS -*-
;;;;
;;;; Copyright (c) 1992, Giuseppe Attardi.
;;;;
;;;; This program is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU Library General Public
;;;; License as published by the Free Software Foundation; either
;;;; version 2 of the License, or (at your option) any later version.
;;;;
;;;; See file '../Copyright' for full details.
(in-package "CLOS")
;;; ======================================================================
;;; Built-in classes
;;; ----------------------------------------------------------------------
(defmethod make-instance ((class built-in-class) &rest initargs)
(declare (ignore initargs))
(error "The built-in class (~A) cannot be instantiated" class))
(defmethod allocate-instance ((class built-in-class) &rest initargs)
(declare (ignore initargs))
(error "The built-in class (~A) cannot be instantiated" class))
(defmethod ensure-class-using-class ((class null) name core:&va-rest rest)
(clos::gf-log "In ensure-class-using-class (class null)%N")
(clos::gf-log " class -> {}%N" name)
(multiple-value-bind (metaclass direct-superclasses options)
(apply #'help-ensure-class rest)
(declare (ignore direct-superclasses))
(setf class (apply #'make-instance metaclass :name name options))
(when name
(si:create-type-name name)
(setf (find-class name) class))))
(defmethod change-class ((instance t) (new-class symbol) core:&va-rest initargs)
(apply #'change-class instance (find-class new-class) initargs))
(defmethod make-instances-obsolete ((class symbol))
(make-instances-obsolete (find-class class))
class)
(defmethod make-instance ((class-name symbol) core:&va-rest initargs)
(apply #'make-instance (find-class class-name) initargs))
(defmethod slot-makunbound-using-class ((class built-in-class) self slotd)
(declare (ignore self slotd))
(error "SLOT-MAKUNBOUND-USING-CLASS cannot be applied on built-in object ~a of class ~a" class (class-of class)))
(defmethod slot-boundp-using-class ((class built-in-class) self slotd)
(declare (ignore class self slotd))
(error "SLOT-BOUNDP-USING-CLASS cannot be applied on built-in objects"))
(defmethod slot-value-using-class ((class built-in-class) self slotd)
(declare (ignore class self slotd))
(error "SLOT-VALUE-USING-CLASS cannot be applied on built-in objects"))
(defmethod (setf slot-value-using-class) (val (class built-in-class) self slotd)
(declare (ignore class self slotd val))
(error "SLOT-VALUE-USING-CLASS cannot be applied on built-in objects"))
(defmethod slot-exists-p-using-class ((class built-in-class) self slotd)
(declare (ignore class self slotd))
nil)
#+threads
(defmethod cas-slot-value-using-class
(old new (class built-in-class) object slotd)
(declare (ignore old new object slotd))
(error "Cannot modify slots of object with built-in-class"))
;;; ======================================================================
;;; STRUCTURES
;;;
;;; As an extension, we allow the use of MAKE-INSTANCE, as well as SLOT-VALUE
;;; and sundry, on structure objects and classes.
;;; However, at least for now we do not go through SHARED-INITIALIZE or
;;; INITIALIZE-INSTANCE when using constructors instead, so specializing those
;;; on structure classes has undefined behavior.
;;; Also note that we don't define whether uninitialized slots are bound, or
;;; what they are bound to if they are bound.
;;; Most of the methods in standard.lsp work fine for structures and don't need
;;; to be specialized here.
(defmethod allocate-instance ((class structure-class) &rest initargs)
(declare (ignore initargs))
(core:allocate-raw-instance class (make-rack-for-class class)))
;;; The slot methods do need to be specialized. FIXME: Could possibly be
;;; cleaned up by making structure-class a subclass of std-class, but with
;;; an improved structure runtime we'd probably need to do something special
;;; here regardless.
(defmethod slot-value-using-class ((class structure-class) self slotd)
(let* ((location (slot-definition-location slotd))
(value (standard-instance-access self location)))
(if (si:sl-boundp value)
value
(values (slot-unbound class self (slot-definition-name slotd))))))
(defmethod slot-boundp-using-class ((class structure-class) self slotd)
(declare (ignore class))
(si:sl-boundp (standard-instance-access self
(slot-definition-location slotd))))
(defmethod (setf slot-value-using-class) (val (class structure-class)
self slotd)
(declare (ignore class))
(setf (standard-instance-access self (slot-definition-location slotd)) val))
(defmethod slot-makunbound-using-class ((class structure-class) instance slotd)
(declare (ignore class))
(setf (standard-instance-access instance (slot-definition-location slotd))
(si:unbound))
instance)
#+threads
(defmethod cas-slot-value-using-class
(old new (class structure-class) object
(slotd standard-effective-slot-definition))
(let ((loc (slot-definition-location slotd)))
(mp:cas (standard-instance-access object loc) old new)))
#+threads
(defmethod atomic-slot-value-using-class
((class structure-class) object (slotd standard-effective-slot-definition))
(let* ((loc (slot-definition-location slotd))
(v (mp:atomic (standard-instance-access object loc))))
(if (si:sl-boundp v)
v
(values (slot-unbound class object (slot-definition-name slotd))))))
#+threads
(defmethod (setf atomic-slot-value-using-class)
(new-value (class structure-class) object
(slotd standard-effective-slot-definition))
(let ((loc (slot-definition-location slotd)))
(setf (mp:atomic (standard-instance-access object loc)) new-value)))
(defmethod finalize-inheritance ((class structure-class))
(call-next-method)
(dolist (slot (class-slots class))
(unless (eq :INSTANCE (slot-definition-allocation slot))
(error "The structure class ~S can't have shared slots" (class-name class)))))
(defun copy-structure (structure)
;; This could be done slightly faster by making copy-structure generic,
;; and having defstruct define a copy-structure method that works without a loop
;; or checking the size.
(let* ((class (class-of structure))
(copy (allocate-instance class))
(size (class-size class)))
(loop for i below size
do (setf (si:instance-ref copy i)
(si:instance-ref structure i)))
copy))