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