Commit | Line | Data |
---|---|---|
730d8ad9 | 1 | /* Copyright (C) 1995,1996,1999,2000,2001, 2003, 2004, 2006, 2008, 2009 Free Software Foundation, Inc. |
1d9ee7c7 | 2 | * |
73be1d9e | 3 | * This library is free software; you can redistribute it and/or |
53befeb7 NJ |
4 | * modify it under the terms of the GNU Lesser General Public License |
5 | * as published by the Free Software Foundation; either version 3 of | |
6 | * the License, or (at your option) any later version. | |
1d9ee7c7 | 7 | * |
53befeb7 NJ |
8 | * This library is distributed in the hope that it will be useful, but |
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
73be1d9e MV |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
11 | * Lesser General Public License for more details. | |
1d9ee7c7 | 12 | * |
73be1d9e MV |
13 | * You should have received a copy of the GNU Lesser General Public |
14 | * License along with this library; if not, write to the Free Software | |
53befeb7 NJ |
15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
16 | * 02110-1301 USA | |
73be1d9e | 17 | */ |
1bbd0b84 | 18 | |
1bbd0b84 | 19 | |
1d9ee7c7 MD |
20 | \f |
21 | ||
da7f71d7 MD |
22 | /* This file and objects.h contains those minimal pieces of the Guile |
23 | * Object Oriented Programming System which need to be included in | |
24 | * libguile. See the comments in objects.h. | |
1d9ee7c7 MD |
25 | */ |
26 | ||
dbb605f5 LC |
27 | #ifdef HAVE_CONFIG_H |
28 | # include <config.h> | |
29 | #endif | |
30 | ||
a0599745 MD |
31 | #include "libguile/_scm.h" |
32 | ||
33 | #include "libguile/struct.h" | |
34 | #include "libguile/procprop.h" | |
35 | #include "libguile/chars.h" | |
36 | #include "libguile/keywords.h" | |
37 | #include "libguile/smob.h" | |
38 | #include "libguile/eval.h" | |
39 | #include "libguile/alist.h" | |
40 | #include "libguile/ports.h" | |
41 | #include "libguile/strings.h" | |
42 | #include "libguile/vectors.h" | |
ef7e1868 AW |
43 | #include "libguile/programs.h" |
44 | #include "libguile/vm.h" | |
a0599745 MD |
45 | |
46 | #include "libguile/validate.h" | |
47 | #include "libguile/objects.h" | |
38c9cccb MV |
48 | #include "libguile/goops.h" |
49 | ||
1d9ee7c7 MD |
50 | \f |
51 | ||
52 | SCM scm_metaclass_standard; | |
1d9ee7c7 | 53 | |
5843e5c9 DH |
54 | /* The cache argument for scm_mcache_lookup_cmethod has one of two possible |
55 | * formats: | |
56 | * | |
57 | * Format #1: | |
58 | * (SCM_IM_DISPATCH ARGS N-SPECIALIZED | |
a12be546 MD |
59 | * #((TYPE1 ... ENV FORMALS FORM ...) ...) |
60 | * GF) | |
61 | * | |
5843e5c9 | 62 | * Format #2: |
a12be546 MD |
63 | * (SCM_IM_HASH_DISPATCH ARGS N-SPECIALIZED HASHSET MASK |
64 | * #((TYPE1 ... ENV FORMALS FORM ...) ...) | |
65 | * GF) | |
66 | * | |
67 | * ARGS is either a list of expressions, in which case they | |
68 | * are interpreted as the arguments of an application, or | |
69 | * a non-pair, which is interpreted as a single expression | |
70 | * yielding all arguments. | |
71 | * | |
72 | * SCM_IM_DISPATCH expressions in generic functions always | |
73 | * have ARGS = the symbol `args' or the iloc #@0-0. | |
74 | * | |
75 | * Need FORMALS in order to support varying arity. This | |
76 | * also avoids the need for renaming of bindings. | |
77 | * | |
78 | * We should probably not complicate this mechanism by | |
79 | * introducing "optimizations" for getters and setters or | |
80 | * primitive methods. Getters and setter will normally be | |
81 | * compiled into @slot-[ref|set!] or a procedure call. | |
82 | * They rely on the dispatch performed before executing | |
83 | * the code which contains them. | |
84 | * | |
85 | * We might want to use a more efficient representation of | |
86 | * this form in the future, perhaps after we have introduced | |
87 | * low-level support for syntax-case macros. | |
88 | */ | |
89 | ||
9de33deb MD |
90 | SCM |
91 | scm_mcache_lookup_cmethod (SCM cache, SCM args) | |
92 | { | |
e11e83f3 | 93 | unsigned long i, mask, n, end; |
9de33deb | 94 | SCM ls, methods, z = SCM_CDDR (cache); |
e11e83f3 | 95 | n = scm_to_ulong (SCM_CAR (z)); /* maximum number of specializers */ |
9de33deb MD |
96 | methods = SCM_CADR (z); |
97 | ||
4057a3e0 | 98 | if (scm_is_simple_vector (methods)) |
e11e83f3 MV |
99 | { |
100 | /* cache format #1: prepare for linear search */ | |
101 | mask = -1; | |
102 | i = 0; | |
4057a3e0 | 103 | end = SCM_SIMPLE_VECTOR_LENGTH (methods); |
e11e83f3 MV |
104 | } |
105 | else | |
9de33deb | 106 | { |
5843e5c9 | 107 | /* cache format #2: compute a hash value */ |
e11e83f3 | 108 | unsigned long hashset = scm_to_ulong (methods); |
c014a02e | 109 | long j = n; |
bab246f3 | 110 | z = SCM_CDDR (z); |
e11e83f3 | 111 | mask = scm_to_ulong (SCM_CAR (z)); |
9de33deb MD |
112 | methods = SCM_CADR (z); |
113 | i = 0; | |
114 | ls = args; | |
d2e53ed6 | 115 | if (!scm_is_null (ls)) |
a12be546 MD |
116 | do |
117 | { | |
d8c40b9f DH |
118 | i += SCM_STRUCT_DATA (scm_class_of (SCM_CAR (ls))) |
119 | [scm_si_hashsets + hashset]; | |
a12be546 MD |
120 | ls = SCM_CDR (ls); |
121 | } | |
d2e53ed6 | 122 | while (j-- && !scm_is_null (ls)); |
9de33deb MD |
123 | i &= mask; |
124 | end = i; | |
125 | } | |
126 | ||
127 | /* Search for match */ | |
128 | do | |
129 | { | |
c014a02e | 130 | long j = n; |
4057a3e0 | 131 | z = SCM_SIMPLE_VECTOR_REF (methods, i); |
9de33deb | 132 | ls = args; /* list of arguments */ |
d2e53ed6 | 133 | if (!scm_is_null (ls)) |
a12be546 MD |
134 | do |
135 | { | |
136 | /* More arguments than specifiers => CLASS != ENV */ | |
bc36d050 | 137 | if (! scm_is_eq (scm_class_of (SCM_CAR (ls)), SCM_CAR (z))) |
a12be546 MD |
138 | goto next_method; |
139 | ls = SCM_CDR (ls); | |
140 | z = SCM_CDR (z); | |
141 | } | |
d2e53ed6 | 142 | while (j-- && !scm_is_null (ls)); |
05b37c17 AW |
143 | /* Fewer arguments than specifiers => CAR != CLASS or `no-method' */ |
144 | if (!scm_is_pair (z) | |
145 | || (!SCM_CLASSP (SCM_CAR (z)) && !scm_is_symbol (SCM_CAR (z)))) | |
5843e5c9 | 146 | return z; |
9de33deb MD |
147 | next_method: |
148 | i = (i + 1) & mask; | |
149 | } while (i != end); | |
150 | return SCM_BOOL_F; | |
151 | } | |
152 | ||
153 | SCM | |
a12be546 | 154 | scm_mcache_compute_cmethod (SCM cache, SCM args) |
9de33deb MD |
155 | { |
156 | SCM cmethod = scm_mcache_lookup_cmethod (cache, args); | |
7888309b | 157 | if (scm_is_false (cmethod)) |
9de33deb MD |
158 | /* No match - memoize */ |
159 | return scm_memoize_method (cache, args); | |
160 | return cmethod; | |
161 | } | |
162 | ||
163 | SCM | |
a12be546 | 164 | scm_apply_generic (SCM gf, SCM args) |
9de33deb | 165 | { |
521ac49b | 166 | SCM cmethod = scm_mcache_compute_cmethod (SCM_GENERIC_METHOD_CACHE (gf), args); |
ef7e1868 AW |
167 | if (SCM_PROGRAM_P (cmethod)) |
168 | return scm_vm_apply (scm_the_vm (), cmethod, args); | |
169 | else if (scm_is_pair (cmethod)) | |
5487977b AW |
170 | return scm_eval_body (SCM_CDR (SCM_CMETHOD_CODE (cmethod)), |
171 | SCM_EXTEND_ENV (SCM_CAR (SCM_CMETHOD_CODE (cmethod)), | |
172 | args, | |
173 | SCM_CMETHOD_ENV (cmethod))); | |
174 | else | |
175 | return scm_apply (cmethod, args, SCM_EOL); | |
9de33deb MD |
176 | } |
177 | ||
178 | SCM | |
a12be546 | 179 | scm_call_generic_0 (SCM gf) |
9de33deb | 180 | { |
a12be546 | 181 | return scm_apply_generic (gf, SCM_EOL); |
9de33deb MD |
182 | } |
183 | ||
184 | SCM | |
a12be546 | 185 | scm_call_generic_1 (SCM gf, SCM a1) |
9de33deb | 186 | { |
1afff620 | 187 | return scm_apply_generic (gf, scm_list_1 (a1)); |
9de33deb MD |
188 | } |
189 | ||
190 | SCM | |
a12be546 MD |
191 | scm_call_generic_2 (SCM gf, SCM a1, SCM a2) |
192 | { | |
1afff620 | 193 | return scm_apply_generic (gf, scm_list_2 (a1, a2)); |
a12be546 MD |
194 | } |
195 | ||
196 | SCM | |
197 | scm_call_generic_3 (SCM gf, SCM a1, SCM a2, SCM a3) | |
9de33deb | 198 | { |
1afff620 | 199 | return scm_apply_generic (gf, scm_list_3 (a1, a2, a3)); |
9de33deb MD |
200 | } |
201 | ||
1d9ee7c7 MD |
202 | void |
203 | scm_init_objects () | |
204 | { | |
a0599745 | 205 | #include "libguile/objects.x" |
1d9ee7c7 | 206 | } |
89e00824 ML |
207 | |
208 | /* | |
209 | Local Variables: | |
210 | c-file-style: "gnu" | |
211 | End: | |
212 | */ |