2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 PyrSlot is a value holder for SC variables.
23 A PyrSlot is an 8-byte value which is either a double precision float or a
24 32-bit tag plus a 32-bit value.
31 #include "SC_Endian.h"
33 #include "PyrErrors.h"
41 Pyrite slots are the size of an 8 byte double. If the upper bits
42 indicate that the double is a 'Not-A-Number' then the upper 32
43 bits are used as a tag to indicate one of a number of other types
44 whose data is in the lower 32 bits.
47 /* some DSPs like the TIC32 do not support 8 byte doubles */
48 /* on such CPUs, set DOUBLESLOTS to zero */
52 /* use the high order bits of an IEEE double NaN as a tag */
58 tagNil
= 0x7FF90005, // nil, false, and true are indicated by the tag alone.
59 tagFalse
= 0x7FF90006, // the lower 32 bits are zero.
62 /* anything else is a double */
63 tagUnused
= 0x7FF9000D
67 ,tagFloat
= 0x7FF9000F /* used only to initialized 4 byte float tags, never compared with */
71 typedef union pyrslot
{
74 #if BYTE_ORDER == BIG_ENDIAN
85 struct PyrBlock
*oblk
;
90 struct PyrInt8Array
*ob
;
91 struct PyrDoubleArray
*od
;
92 struct PyrSymbolArray
*osym
;
93 struct PyrProcess
*op
;
95 struct PyrInterpreter
*oi
;
97 #if BYTE_ORDER == LITTLE_ENDIAN
98 // need to swap on intel <sk>
100 #endif // LITTLE_ENDIAN
105 these are some defines to make accessing the structure less verbose.
106 obviously it polutes the namespace of identifiers beginning with 'u'.
130 #define uosym s.u.osym
131 #define uoblk s.u.oblk
141 Note that on the PowerPC, the fastest way to copy a slot is to
142 copy the double field, not the struct.
145 inline int GetTag(PyrSlot
* slot
) { return slot
->utag
; }
147 /* some macros for setting values of slots */
148 inline void SetInt(PyrSlot
* slot
, int val
) { (slot
)->utag
= tagInt
; (slot
)->ui
= (val
); }
149 inline void SetObject(PyrSlot
* slot
, struct PyrObjectHdr
* val
) { (slot
)->utag
= tagObj
; (slot
)->uo
= (PyrObject
*)(val
); }
150 inline void SetSymbol(PyrSlot
* slot
, PyrSymbol
*val
) { (slot
)->utag
= tagSym
; (slot
)->us
= (val
); }
151 inline void SetChar(PyrSlot
* slot
, char val
) { (slot
)->utag
= tagChar
; (slot
)->uc
= (val
); }
152 inline void SetPtr(PyrSlot
* slot
, void* val
) { (slot
)->utag
= tagPtr
; (slot
)->uptr
= (void*)(val
); }
153 inline void SetObjectOrNil(PyrSlot
* slot
, PyrObject
* val
)
156 (slot
)->utag
= tagObj
;
159 (slot
)->utag
= tagNil
;
164 inline void SetTrue(PyrSlot
* slot
) { (slot
)->utag
= tagTrue
; (slot
)->ui
= 0; }
165 inline void SetFalse(PyrSlot
* slot
) { (slot
)->utag
= tagFalse
; (slot
)->ui
= 0; }
166 inline void SetBool(PyrSlot
* slot
, bool test
) { (slot
)->utag
= ((test
) ? tagTrue
: tagFalse
); (slot
)->ui
= 0; }
167 inline void SetNil(PyrSlot
* slot
) { (slot
)->utag
= tagNil
; (slot
)->ui
= 0; }
170 inline void SetFloat(PyrSlot
* slot
, double val
) { (slot
)->uf
= (val
); }
172 inline void SetFloat(PyrSlot
* slot
, double val
) { (slot
)->utag
= s_float
; (slot
)->uf
= (val
); }
176 inline bool IsObj(PyrSlot
* slot
) { return ((slot
)->utag
== tagObj
); }
177 inline bool NotObj(PyrSlot
* slot
) { return ((slot
)->utag
!= tagObj
); }
179 inline bool IsNil(PyrSlot
* slot
) { return ((slot
)->utag
== tagNil
); }
180 inline bool NotNil(PyrSlot
* slot
) { return ((slot
)->utag
!= tagNil
); }
182 inline bool IsFalse(PyrSlot
* slot
) { return ((slot
)->utag
== tagFalse
); }
183 inline bool IsTrue(PyrSlot
* slot
) { return ((slot
)->utag
== tagTrue
); }
185 inline bool SlotEq(PyrSlot
* a
, PyrSlot
* b
) { return ((a
)->ui
== (b
)->ui
&& (a
)->utag
== (b
)->utag
); }
187 inline bool IsSym(PyrSlot
* slot
) { return ((slot
)->utag
== tagSym
); }
188 inline bool NotSym(PyrSlot
* slot
) { return ((slot
)->utag
!= tagSym
); }
190 inline bool IsChar(PyrSlot
* slot
) { return ((slot
)->utag
== tagChar
); }
191 inline bool NotChar(PyrSlot
* slot
) { return ((slot
)->utag
!= tagChar
); }
193 inline bool IsInt(PyrSlot
* slot
) { return ((slot
)->utag
== tagInt
); }
194 inline bool NotInt(PyrSlot
* slot
) { return ((slot
)->utag
!= tagInt
); }
196 inline bool IsFloatTag(int tag
) { return ((tag
& 0xFFFFFFF0) != 0x7FF90000); }
197 inline bool IsFloat(PyrSlot
* slot
) { return (((slot
)->utag
& 0xFFFFFFF0) != 0x7FF90000); }
198 inline bool NotFloat(PyrSlot
* slot
) { return (((slot
)->utag
& 0xFFFFFFF0) == 0x7FF90000); }
200 inline bool IsPtr(PyrSlot
* slot
) { return ((slot
)->utag
== tagPtr
); }
201 inline bool NotPtr(PyrSlot
* slot
) { return ((slot
)->utag
!= tagPtr
); }
203 inline void SetRawChar(PyrSlot
* slot
, int val
) { assert(IsChar(slot
)); slot
->uc
= val
; }
204 inline void SetRaw(PyrSlot
* slot
, int val
) { assert(IsInt(slot
)); slot
->ui
= val
; }
205 inline void SetRaw(PyrSlot
* slot
, long val
) { assert(IsInt(slot
)); slot
->ui
= val
; }
206 inline void SetRaw(PyrSlot
* slot
, PyrObject
* val
) { assert(IsObj(slot
)); slot
->uo
= val
; }
207 inline void SetRaw(PyrSlot
* slot
, PyrSymbol
* val
) { assert(IsSym(slot
)); slot
->us
= val
; }
208 inline void SetRaw(PyrSlot
* slot
, void * val
) { assert(IsPtr(slot
)); slot
->uptr
= val
; }
209 inline void SetRaw(PyrSlot
* slot
, double val
) { assert(IsFloat(slot
)); SetFloat(slot
, val
); }
211 inline void SetTagRaw(PyrSlot
* slot
, int tag
) { slot
->utag
= tag
; }
213 template <typename numeric_type
>
214 inline int slotVal(PyrSlot
* slot
, numeric_type
*value
)
217 *value
= static_cast<numeric_type
>(slot
->uf
);
219 } else if (IsInt(slot
)) {
220 *value
= static_cast<numeric_type
>(slot
->ui
);
227 inline int slotFloatVal(PyrSlot
*slot
, float *value
)
229 return slotVal
<float>(slot
, value
);
232 inline int slotIntVal(PyrSlot
*slot
, int *value
)
234 return slotVal
<int>(slot
, value
);
237 inline int slotDoubleVal(PyrSlot
*slot
, double *value
)
239 return slotVal
<double>(slot
, value
);
242 inline int slotSymbolVal(PyrSlot
*slot
, PyrSymbol
**symbol
)
244 if (!IsSym(slot
)) return errWrongType
;
249 inline void* slotRawPtr(PyrSlot
*slot
)
251 assert(IsPtr(slot
) || (slot
->s
.u
.ptr
== NULL
&& IsNil(slot
)));
252 return slot
->s
.u
.ptr
;
255 inline PyrBlock
* slotRawBlock(PyrSlot
*slot
)
257 return slot
->s
.u
.oblk
;
260 inline PyrSymbolArray
* slotRawSymbolArray(PyrSlot
*slot
)
262 return slot
->s
.u
.osym
;
265 inline PyrDoubleArray
* slotRawDoubleArray(PyrSlot
*slot
)
270 inline PyrInt8Array
* slotRawInt8Array(PyrSlot
*slot
)
275 inline PyrMethod
* slotRawMethod(PyrSlot
*slot
)
280 inline PyrThread
* slotRawThread(PyrSlot
*slot
)
285 inline PyrString
* slotRawString(PyrSlot
*slot
)
290 inline PyrList
* slotRawList(PyrSlot
*slot
)
295 inline PyrFrame
* slotRawFrame(PyrSlot
*slot
)
300 inline PyrClass
* slotRawClass(PyrSlot
*slot
)
305 inline PyrInterpreter
* slotRawInterpreter(PyrSlot
*slot
)
310 inline PyrSymbol
* slotRawSymbol(PyrSlot
*slot
)
316 inline int slotRawChar(PyrSlot
*slot
)
318 assert(IsChar(slot
));
322 inline int slotRawInt(PyrSlot
*slot
)
328 inline double slotRawFloat(PyrSlot
*slot
)
330 assert(IsFloat(slot
));
334 inline PyrObject
* slotRawObject(PyrSlot
*slot
)
340 inline void slotCopy(PyrSlot
*dst
, PyrSlot
*src
)
342 double *dstp
= (double*)dst
;
343 double *srcp
= (double*)src
;
347 inline void slotCopy(PyrSlot
*dst
, PyrSlot
*src
, int num
)
349 double *dstp
= (double*)dst
- 1;
350 double *srcp
= (double*)src
- 1;
351 for (int i
=0;i
<num
;++i
) { *++dstp
= *++srcp
; }