1 /*
2 * Object-inl.h - inline functions for Object.
3 *
4 * Copyright (c) 2008 Higepon(Taro Minowa) <higepon@users.sourceforge.jp>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
23 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * $Id: Object-inl.h 261 2008-07-25 06:16:44Z higepon $
30 */
31
32 #ifndef SCHEME_OBJECT_INL_
33 #define SCHEME_OBJECT_INL_
34
35 namespace scheme {
36
isFixnum()37 inline bool Object::isFixnum() const
38 {
39 return tag() == 1;
40 }
41
isBoolean()42 inline bool Object::isBoolean() const
43 {
44 return isFalse() || isTrue();
45 }
46
isInstruction()47 inline bool Object::isInstruction() const
48 {
49 return (static_cast<intptr_t>(val) & 31) == 14;
50 }
51
isCompilerInstruction()52 inline bool Object::isCompilerInstruction() const
53 {
54 return (static_cast<intptr_t>(val) & 31) == 30;
55 }
56
57
isChar()58 inline bool Object::isChar() const
59 {
60 return (static_cast<intptr_t>(val) & 0x07L) == 2;
61 }
62
toChar()63 inline ucs4char Object::toChar() const
64 {
65 MOSH_ASSERT(isChar());
66 return static_cast<ucs4char>(val) >> 3;
67 }
68
toFixnum()69 inline fixedint Object::toFixnum() const
70 {
71 MOSH_ASSERT(isFixnum());
72 return static_cast<fixedint>(val) >> 2;
73 }
74
toInstruction()75 inline int Object::toInstruction() const
76 {
77 MOSH_ASSERT(isInstruction());
78 return static_cast<int>(val) >> 5;
79 }
80
toCompilerInstruction()81 inline int Object::toCompilerInstruction() const
82 {
83 MOSH_ASSERT(isCompilerInstruction());
84 return static_cast<int>(val) >> 5;
85 }
86
isNil()87 inline bool Object::isNil() const
88 {
89 return *this == MAKE_CONST(CONST_NIL);
90 }
91
isEof()92 inline bool Object::isEof() const
93 {
94 return *this == MAKE_CONST(CONST_EOF);
95 }
96
isUndef()97 inline bool Object::isUndef() const
98 {
99 return *this == MAKE_CONST(CONST_UNDEF);
100 }
101
isUnbound()102 inline bool Object::isUnbound() const
103 {
104 return *this == MAKE_CONST(CONST_UNBOUND);
105 }
106
isTrue()107 inline bool Object::isTrue() const
108 {
109 return *this == MAKE_CONST(CONST_TRUE);
110 }
111
isFalse()112 inline bool Object::isFalse() const
113 {
114 return *this == MAKE_CONST(CONST_FALSE);
115 }
116
isProcedure()117 inline bool Object::isProcedure() const
118 {
119 return isClosure() || isCProcedure() || isRegexp() || isRegMatch() || isCallable() || isContinuation();
120 }
121
isHashTable()122 inline bool Object::isHashTable() const
123 {
124 return isEqHashTable() || isGenericHashTable() || isEqvHashTable();
125 }
126
127 inline bool Object::operator==(Object o) const
128 {
129 return val == o.val;
130 }
131
132 inline bool Object::operator!=(Object o) const
133 {
134 return val != o.val;
135 }
136
toHashTable()137 inline HashTable* Object::toHashTable() const
138 {
139 return reinterpret_cast<HashTable*>(reinterpret_cast<HeapObject*>(val)->obj);
140 }
141
toObjectPointer()142 inline Object* Object::toObjectPointer() const
143 {
144 #ifdef DEBUG_VERSION
145 MOSH_ASSERT(isObjectPointer());
146 return reinterpret_cast<Object*>(reinterpret_cast<HeapObject*>(val)->obj);
147 #else
148 return reinterpret_cast<Object*>(val);
149 #endif
150 }
151
isObjectPointer()152 inline bool Object::isObjectPointer() const
153 {
154 #ifdef DEBUG_VERSION
155 return isHeapObject()
156 && reinterpret_cast<HeapObject*>(val)->type == HeapObject::ObjectPointer;
157 #else
158 return false;
159 #endif
160 }
161
isRawPointer()162 inline bool Object::isRawPointer() const
163 {
164 return (val & 0x03) == 0;
165 }
166
eq(Object o)167 inline bool Object::eq(Object o) const
168 {
169 return operator==(o);
170 }
171
makeFixnum(fixedint n)172 inline Object Object::makeFixnum(fixedint n)
173 {
174 return Object((n << 2) + 1);
175 }
176
makeRaw(int n)177 inline Object Object::makeRaw(int n)
178 {
179 return Object(n);
180 }
181
makeRaw(void * n)182 inline Object Object::makeRaw(void* n)
183 {
184 return Object(reinterpret_cast<intptr_t>(n));
185 }
186
makeInstruction(int n)187 inline Object Object::makeInstruction(int n)
188 {
189 return Object((n << 5) + 14);
190 }
191
makeCompilerInstruction(int n)192 inline Object Object::makeCompilerInstruction(int n)
193 {
194 #ifdef USE_DIRECT_THREADED_CODE
195 return Object((n << 5) + 30);
196 #else
197 return Object((n << 5) + 14);
198 #endif
199 }
200
makeChar(ucs4char ch)201 inline Object Object::makeChar(ucs4char ch)
202 {
203 return Object((ch << 3) + 2);
204 }
205
makeConst(int n)206 inline Object Object::makeConst(int n)
207 {
208 return Object(MAKE_CONST(n));
209 }
210
makeVector(int n,Object o)211 inline Object Object::makeVector(int n, Object o)
212 {
213 return Object(n, o);
214 }
215
makeBool(bool a)216 inline Object Object::makeBool(bool a)
217 {
218 return a ? Object::True : Object::False;
219 }
220
isHeapObject()221 inline bool Object::isHeapObject() const
222 {
223 return isRawPointer() && ((reinterpret_cast<HeapObject*>(val)->type & 0x03) == 0x03);
224 }
225
toPair()226 inline Pair* Object::toPair() const
227 {
228 return reinterpret_cast<Pair*>(val);
229 }
230
toAnnotatedPair()231 inline AnnotatedPair* Object::toAnnotatedPair() const
232 {
233 return reinterpret_cast<AnnotatedPair*>(val);
234 }
235
makeObjectPointer(Object * p)236 inline Object Object::makeObjectPointer(Object* p)
237 {
238 #ifdef DEBUG_VERSION
239 return Object(reinterpret_cast<intptr_t>(new HeapObject(HeapObject::ObjectPointer,
240 reinterpret_cast<intptr_t>(p))));
241 #else
242 return Object(reinterpret_cast<intptr_t>(p));
243 #endif
244 }
245
isNumber()246 inline bool Object::isNumber() const
247 {
248 return isReal() || isCompnum();
249 }
250
isComplex()251 inline bool Object::isComplex() const
252 {
253 return isReal() || isCompnum();
254 }
255
isExactInteger()256 inline bool Object::isExactInteger() const
257 {
258 return isFixnum() || isBignum();
259 }
260
isInputPort()261 inline bool Object::isInputPort() const
262 {
263 return isTextualInputPort() || isBinaryInputPort() || isBinaryInputOutputPort() || isTextualInputOutputPort();
264 }
265
isOutputPort()266 inline bool Object::isOutputPort() const
267 {
268 return isTextualOutputPort() || isBinaryOutputPort() || isTextualInputOutputPort() | isBinaryInputOutputPort();
269 }
270
isBinaryPort()271 inline bool Object::isBinaryPort() const
272 {
273 return isBinaryInputPort() || isBinaryOutputPort() || isBinaryInputOutputPort();
274 }
275
isTextualPort()276 inline bool Object::isTextualPort() const
277 {
278 return isTextualInputPort() || isTextualOutputPort() || isTextualInputOutputPort();
279 }
280
isPort()281 inline bool Object::isPort() const
282 {
283 return isInputPort() || isOutputPort();
284 }
285
makeObjectArray(int size)286 inline Object* Object::makeObjectArray(int size)
287 {
288 #ifdef USE_BOEHM_GC
289 return new(GC) Object[size];
290 #else
291 return new Object[size];
292 #endif
293 }
294
makeObjectArrayLocal(int size)295 inline Object* Object::makeObjectArrayLocal(int size)
296 {
297 #ifdef USE_BOEHM_GC
298 return static_cast<Object *>
299 (GC_MALLOC_IGNORE_OFF_PAGE(sizeof(Object *)*size));
300 #else
301 return new Object[size];
302 #endif
303 }
304
305 // private
tag()306 inline uint8_t Object::tag() const
307 {
308 return (static_cast<intptr_t>(val)) & 0x03;
309 }
310
311 } // namespace scheme
312
313 #endif // SCHEME_OBJECT_INL_
314